DynamoDB查询依据包含Node.js数组中的值之一

Ohs*_*sik 5 javascript node.js amazon-dynamodb

是否可以使用[apple, orange]类别数组(也是一个数组,如下所示)进行查询,并获取包含apple或值的数据orange

row1 | "category": [apple, orange, banana, watermelon]
row2 | "category": [banana, watermelon]
row3 | "category": [orange, watermelon]
Run Code Online (Sandbox Code Playgroud)

我期望得到row1, row3包含apple或的结果orange

not*_*est 9

您可以使用CONTAINS函数检查列表中的值。但是,如果要检查多个值,则需要对每个值使用逻辑或条件

列表支持CONTAINS:在评估“ a CONTAINS b”时,“ a”可以是列表;但是,“ b”不能是集合,地图或列表。

例:-

var params = {
    TableName : 'tableName',
    FilterExpression: "contains (category, :category1) OR contains (category, :category2)",
    ExpressionAttributeValues : {   
        ':category1' : "apple",
        ':category2' : "orange"
    }
};
Run Code Online (Sandbox Code Playgroud)

注意:-

我以为您将使用Scan API。如果您使用的是Query API,请添加KeyConditionExpression


War*_*rad 5

问题问的是Query,但似乎不清楚是否Scan正在使用该技术。我将回答每个部分。

  1. Scan非常昂贵,Query应尽可能使用。 Scan轻松支持使用contains来执行您的要求。

    await db.scan({
      TableName : 'tableName',
      FilterExpression: "contains (category, :category1) OR contains (category, :category2)",
      ExpressionAttributeValues : {   
        ':category1' : "apple",
        ':category2' : "orange"
      }
    }).promise();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 鉴于 Scan 效率低下,最好有一个策略,可以使用Query. Query支持的Contains语法,另外必须运行只有一个HASH值。与不同的两个不同行HASH的值不能在同一返回Query。假设满足此条件,则需要构建自定义索引。有几种方法可以做到这一点,具体取决于您拥有的类别数量以及是否可以分配多个类别以到达行。对于每行 1 只猫,单个索引列有效。否则,我们将需要构造一个能够使用其他运算符之一的索引列。
    该列需要包含该行所有类别的复合值,f(column_value, category_value_check) = true以便所有可能的类别。为了构建这样的复合值,亚马逊建议使用Z-Index