如何在查询Dynamodb时过滤嵌套数组对象字段?

huangapple go评论63阅读模式
英文:

How can I filter nested array object fields when querying Dynamodb?

问题

I have a dynamodb item which looks like:

{
 "taxAmounts": [
  {
   "amount": {
    "currency": "AUD",
    "value": 209
   },
   "name": "GST"
  }
 ]
}

I am looking for a filter to filter on the name field of taxAmounts. I have tried:

--filter-expression "contains (taxAmounts.#name, :gst)"
--expression-attribute-values '{" :gst": {"M": { "name": {"S":  "GST"}}}}'
-expression-attribute-names '{"#name": "name"}'

but it doesn't return any item. What is the right way to filter them?

英文:

I have a dynamodb item which looks like:

{
 "taxAmounts": [
  {
   "amount": {
    "currency": "AUD",
    "value": 209
   },
   "name": "GST"
  }
 ]
}

I am looking for a filter to filter on the name field of taxAmounts. I have tired:

--filter-expression "contains (taxAmounts.#name, :gst)"
--expression-attribute-values '{":gst":{"M": { "name": {"S":  "GST"}}}}'
-expression-attribute-names '{"#name": "name"}'

but it doesn't return any item. What is the right way to filter them?
but

答案1

得分: 0

taxAmounts 是一个列表,所以你需要使用 [n] 来选择第 n 个元素。"GST" 是一个字符串,所以不需要担心 Map 数据类型。

尝试这样做:

--filter-expression "contains (taxAmounts[0].#name, :gst)"
--expression-attribute-values '{ ":gst": { "S": "GST" }'
--expression-attribute-names '{"#name": "name"}'

编辑

根据您和Hunterhacker的评论进行编辑。如果您想要搜索整个列表而不仅仅是第 n 个元素,您可以考虑重新组织您的列表为一个 Map。示例:

{
  "taxAmounts": {
    "GST" : {
      "amount": {
        "currency": "AUD",
        "value": 209
      }
    },
    "TAX2": {...},
    ...
  }
}

然后,您可以使用 attribute_exists 函数进行搜索。

FilterExpression = 'attribute_exists(#0.#1)',
ExpressionAttributeNames = {
    "#0": "taxAmounts",
    "#1": "GST"
}

说到重新组织,scan 本来就是一个昂贵的操作。过滤器不能帮助减少扫描的项,因为它只在扫描之后和返回响应之前对结果进行过滤。考虑创建第二个表,例如 taxAmounts,将 GSTTAX2 等作为排序键。

英文:

taxAmounts is a list, so you need [n] to select the n-th element. "GST" is a string, so no need to bother about the Map data type.

Try this:

--filter-expression "contains (taxAmounts[0].#name, :gst)"
--expression-attribute-values '{ ":gst": { "S": "GST" }'
--expression-attribute-names '{"#name": "name"}'

EDIT

Editing based on your and Hunterhacker's comment. If you want to search the entire list instead of only the n-th element, you may consider re-structuring your list into a map. Example:

{
  "taxAmounts": {
    "GST" : {
      "amount": {
        "currency": "AUD",
        "value": 209
      }
    },
    "TAX2": {...},
    ...
  }
}

You can then search using the attribute_exists function.

FilterExpression = 'attribute_exists(#0.#1)',
ExpressionAttributeNames = {
    "#0": "taxAmounts",
    "#1": "GST"
}

Speaking of re-structuring, scan is an expensive operation in the first place. Filter does not help to reduce the scanned items, as it only filters the result after the scan and before returning the response. Consider having a second table, say taxAmounts, having GST, TAX2, etc. as the Sort Key.

huangapple
  • 本文由 发表于 2023年2月27日 15:54:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75577957.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定