Dynamodb 的 boto3 中 FilterExpression 中的列表理解

List comprehensions in FilterExpression in boto3 for Dynamodb

所以我在 dynamodb 的数据库中有一些项目,它看起来有点像这样,其中名称是主键

'name': {'S': 'bob'},
'users': {'L': [
    {'M': {
        'user_id': {'S': 'xxx'},
        'share': {'N': '1'}}},
    {'M': {
        'user_id': {'S': 'yyy'},
        'share': {'N': '4'}}}]}

现在我的问题是 users 是一个字典列表,我想知道是否有任何方法可以扫描 table 以在有特定 user_id 在它的用户列表中。

我知道在 python 中我会做一个列表理解来得到一个 user_id 的列表,然后只做一个 user_id in [user['user_id'] for user in users],这就是测试,但我不确定如何在 DynamoDB 扫描中执行此操作 FilterExpression.

我只是想避免项目看起来像这样:

'name': {'S': 'bob'},
'users': {'L': [
    {'M': {
        'user_id': {'S': 'xxx'},
        'share': {'N': '1'}}},
    {'M': {
        'user_id': {'S': 'yyy'},
        'share': {'N': '4'}}}]}
'user_ids': {'L': [
    {'S': 'xxx'},
    {'S': 'yyy'}]}

因为感觉有点像所谓的"code smell"。但这将解决问题,因为过滤器表达式只是 :user_id in user_ids

DynamoDB 没有过滤列表数据类型 中地图中存在的数据的功能。用户列表具有用户 ID 和共享属性。如果您知道用户 ID 和份额的值,则可以使用 CONTAINS 运算符来过滤数据。

请注意,正如您在 OP 中提到的,DynamoDB 中的 IN 运算符不能那样使用。请参阅下面的说明。

IN : Checks for matching elements within two sets.

AttributeValueList can contain one or more AttributeValue elements of type String, Number, or Binary (not a set type). These attributes are compared against an existing set type attribute of an item. If any elements of the input set are present in the item attribute, the expression evaluates to true.

var params = {
        TableName: "tablenames",    
        FilterExpression: "contains (#users, :usersDetails)",
        ExpressionAttributeNames: { '#users'  : 'users'},
        ExpressionAttributeValues: {
            ":usersDetails": {'user_id' : 'xxx', 'share' : 1}

        }
};