Amazon dynamodb 如何在DynamoDB中按数组(或嵌套对象)中的元素进行过滤

Amazon dynamodb 如何在DynamoDB中按数组(或嵌套对象)中的元素进行过滤,amazon-dynamodb,dynamodb-queries,Amazon Dynamodb,Dynamodb Queries,我的数据如下: [ { orgId: "ABC", categories: [ "music", "dance" ] }, { orgId: "XYZ", categories: [ "math", "science", "art" ] }, ... ] { TableName: "site", IndexName: "orgId-lastCapt

我的数据如下:

[
  {
    orgId: "ABC",
    categories: [
      "music",
      "dance"
    ]
  },
  {
    orgId: "XYZ",
    categories: [
      "math",
      "science",
      "art"
    ]
  },
  ...
]
  {
    TableName: "site",
    IndexName: "orgId-lastCaptured-index",
    KeyConditions: {
      orgId: {
        ComparisonOperator: "EQ",
        AttributeValueList: [orgId],
      },
    },
    QueryFilter: {
      categories: {
        ComparisonOperator: "CONTAINS",
        AttributeValueList: [myVariable],
      }
    }
  }
我有
orgId
上的主键,我想使用DynamoDB
query
过滤并返回类别为“science”的项目

(类别不需要是任何索引的一部分:我愿意接受额外的工作开销,前提是我可以在Dynamo本身中进行查询。)

我要把这件事做好,真是费了好大劲。我可以很容易地将
类别
更改为嵌套对象(如果有帮助的话)

但是在DynamoDB中,比较运算符非常有限,似乎无法按数组元素或嵌套对象进行过滤

如果不是,这里有什么更好的方法?要将每个类别转换为其自己的第一级属性,例如:

[
  {
    orgId: "XYZ",
    category_math: true,
    category_science: true
  }
]
当然不是

 var params = {
  ExpressionAttributeValues: {
   ":orgIdValue": {
     S: "XYZ"
    },
   ":categoriesValue": {
     S: "science"
    }
  }, 
  KeyConditionExpression: "orgId = :orgIdValue", 
  FilterExpression : "categories CONTAINS :categoriesValue", 
  TableName: "MYTABLE"
 };
 dynamodb.query(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
 });
包含:检查子序列或集合中的值。 AttributeValue列表只能包含一个类型为的AttributeValue元素 字符串、数字或二进制(不是集合类型)。如果 比较类型为String,然后运算符检查 子串匹配。如果比较的目标属性的类型为 二进制,然后运算符查找 匹配输入如果比较的目标属性是集合 (“SS”、“NS”或“BS”),如果发现 与集合中的任何成员完全匹配。支持包含 列表:评估“a包含b”时,“a”可以是列表;然而,“b” 不能是集合、映射或列表

类别是顶级属性,实际上没有任何嵌套属性。顶级标量属性可以被索引。尽管类别是顶级的,但它不是一个标量属性(它是一个集合),因此您无法为其编制索引


您可以使用FilterExpression缩小查询范围,也可以使用列表上的CONTAINS comparator。

根据文档,上面给出的答案应该可以使用。但是当使用Node.JS AWS DynamoDB SDK时,它不会。我特别尝试:

  {
    TableName: "site",
    IndexName: "orgId-lastCaptured-index",
    KeyConditionExpression: "orgId = :orgId",
    FilterExpression: "categories CONTAINS :categoriesValue",
    ExpressionAttributeValues: {
      ":orgId": orgId,
      ":categoriesValue": myVariable,
    }
  }
这导致了以下错误:
{ValidationException:Invalid FilterExpression:语法错误;标记:“CONTAINS”,靠近:“categories CONTAINS:categoriesValue”

我将查询调整为备选查询格式,如下所示:

[
  {
    orgId: "ABC",
    categories: [
      "music",
      "dance"
    ]
  },
  {
    orgId: "XYZ",
    categories: [
      "math",
      "science",
      "art"
    ]
  },
  ...
]
  {
    TableName: "site",
    IndexName: "orgId-lastCaptured-index",
    KeyConditions: {
      orgId: {
        ComparisonOperator: "EQ",
        AttributeValueList: [orgId],
      },
    },
    QueryFilter: {
      categories: {
        ComparisonOperator: "CONTAINS",
        AttributeValueList: [myVariable],
      }
    }
  }
这就像预期的那样工作,过滤返回的结果,以便
类别
变量具有与
myVariable
匹配的元素

更新:您现在可以执行
CONTAINS
操作,而无需使用已弃用的
QueryFilter
语法:
FilterExpression:“CONTAINS(categories,:categoriesValue)”

谢谢。这应该可以工作,但无论出于何种原因,它都不能工作。它返回
无效的FilterExpression:语法错误;标记:“CONTAINS”
。但是,它引导我找到了一个可行的解决方案(使用):
{…QueryFilter:{类别:{比较运算符:“包含”,属性值列表:[myCategoryVariable],}…}