DynamoDb 检查给定 SS 中是否包含 SS 属性
DynamoDb check that a SS attribute in contained in a given SS
假设我有这个模式:
source_id -> String, HashKey
created_at -> String, RangeKey
required_capabilities -> StringSet
required_capabilities 是我们需要在查询中提供的一组字符串,以便能够检索特定元素。
例如:
如果我有这三个元素:
{
"source_id": "1",
"created_at": "2021-01-18T10:53:25Z",
"required_capabilities": ["Cap1", "Cap2", "Cap3"]
},
{
"source_id": "1",
"created_at": "2021-01-18T10:59:31Z",
"required_capabilities": ["Cap1", "Cap3"]
},
{
"source_id": "1",
"created_at": "2021-01-18T11:05:15Z"
}
我想创建一个查询,过滤例如 source_id = "1" 并提供带有 required_capabilities = ["Cap1", "Cap3", "Cap4"]
.
的 FilterExpression
我希望结果是:
{
"source_id": "1",
"created_at": "2021-01-18T10:59:31Z",
"required_capabilities": ["Cap1", "Cap3"] // Since I've provided "Cap1", "Cap3" and "Cap4"
},
{
"source_id": "1",
"created_at": "2021-01-18T11:05:15Z" // Since it doesn't require any capability.
}
我尝试了如下的 IN 运算符,因为存储的 StringSet 应该在给定的 SS 中(或包含在其中),但它没有用。
aws dynamodb query --table-name TableName --key-condition-expression "source_id = :id" --filter-expression "required_capabilities IN (:rq)" --expression-attribute-values '{":id": {"S": "1"}, ":rq": { "SS": ["Cap1", "Cap3", "Cap4"] }}'
它仅在我提供完全相同的 StringSet 时有效,但如果我提供的集合包含已保存的字符串集并且还具有更多值,则它不会 return 任何东西。
您的问题似乎与 IN
关键字的使用有关,该关键字不适用于集合。来自 the docs on conditionals
IN : Checks for matching elements in a list.
AttributeValueList can contain one or more AttributeValue elements of type String, Number, or Binary. These attributes are compared against an existing attribute of an item. If any elements of the input are equal to the item attribute, the expression evaluates to true.
我相信您需要 CONTAINS
关键字:
CONTAINS : Checks for a subsequence, or value in a set.
AttributeValueList can contain only one AttributeValue element of type String, Number, or Binary (not a set type). If the target attribute of the comparison is of type String, then the operator checks for a substring match. If the target attribute of the comparison is of type Binary, then the operator looks for a subsequence of the target that matches the input. If the target attribute of the comparison is a set ("SS", "NS", or "BS"), then the operator evaluates to true if it finds an exact match with any member of the set. CONTAINS is supported for lists: When evaluating "a CONTAINS b", "a" can be a list; however, "b" cannot be a set, a map, or a list.
实际上,我发现 dynamodb 不支持我需要的用例,所以我找到了解决方法。
基本上,我没有将 required_capabilities
建模为 StringSet,而是创建了一个名为 required_capability
的字段,其中包含一个必需的功能(到目前为止对我来说没问题)并使用 IN
运算符检查。
如果将来我需要检查不止一种能力,我只需要添加新字段required_capability_2
和required_capability_3
。
这显然不理想,但我想这已经足够了,考虑到我不会在单个记录中拥有很多所需的功能,通常是一个,也许两个。
假设我有这个模式:
source_id -> String, HashKey
created_at -> String, RangeKey
required_capabilities -> StringSet
required_capabilities 是我们需要在查询中提供的一组字符串,以便能够检索特定元素。
例如: 如果我有这三个元素:
{
"source_id": "1",
"created_at": "2021-01-18T10:53:25Z",
"required_capabilities": ["Cap1", "Cap2", "Cap3"]
},
{
"source_id": "1",
"created_at": "2021-01-18T10:59:31Z",
"required_capabilities": ["Cap1", "Cap3"]
},
{
"source_id": "1",
"created_at": "2021-01-18T11:05:15Z"
}
我想创建一个查询,过滤例如 source_id = "1" 并提供带有 required_capabilities = ["Cap1", "Cap3", "Cap4"]
.
我希望结果是:
{
"source_id": "1",
"created_at": "2021-01-18T10:59:31Z",
"required_capabilities": ["Cap1", "Cap3"] // Since I've provided "Cap1", "Cap3" and "Cap4"
},
{
"source_id": "1",
"created_at": "2021-01-18T11:05:15Z" // Since it doesn't require any capability.
}
我尝试了如下的 IN 运算符,因为存储的 StringSet 应该在给定的 SS 中(或包含在其中),但它没有用。
aws dynamodb query --table-name TableName --key-condition-expression "source_id = :id" --filter-expression "required_capabilities IN (:rq)" --expression-attribute-values '{":id": {"S": "1"}, ":rq": { "SS": ["Cap1", "Cap3", "Cap4"] }}'
它仅在我提供完全相同的 StringSet 时有效,但如果我提供的集合包含已保存的字符串集并且还具有更多值,则它不会 return 任何东西。
您的问题似乎与 IN
关键字的使用有关,该关键字不适用于集合。来自 the docs on conditionals
IN : Checks for matching elements in a list. AttributeValueList can contain one or more AttributeValue elements of type String, Number, or Binary. These attributes are compared against an existing attribute of an item. If any elements of the input are equal to the item attribute, the expression evaluates to true.
我相信您需要 CONTAINS
关键字:
CONTAINS : Checks for a subsequence, or value in a set. AttributeValueList can contain only one AttributeValue element of type String, Number, or Binary (not a set type). If the target attribute of the comparison is of type String, then the operator checks for a substring match. If the target attribute of the comparison is of type Binary, then the operator looks for a subsequence of the target that matches the input. If the target attribute of the comparison is a set ("SS", "NS", or "BS"), then the operator evaluates to true if it finds an exact match with any member of the set. CONTAINS is supported for lists: When evaluating "a CONTAINS b", "a" can be a list; however, "b" cannot be a set, a map, or a list.
实际上,我发现 dynamodb 不支持我需要的用例,所以我找到了解决方法。
基本上,我没有将 required_capabilities
建模为 StringSet,而是创建了一个名为 required_capability
的字段,其中包含一个必需的功能(到目前为止对我来说没问题)并使用 IN
运算符检查。
如果将来我需要检查不止一种能力,我只需要添加新字段required_capability_2
和required_capability_3
。
这显然不理想,但我想这已经足够了,考虑到我不会在单个记录中拥有很多所需的功能,通常是一个,也许两个。