如何使用多个索引查询 AWS DynamoDB?

Posted

技术标签:

【中文标题】如何使用多个索引查询 AWS DynamoDB?【英文标题】:How to query AWS DynamoDB using multiple Indexes? 【发布时间】:2019-09-26 19:42:41 【问题描述】:

我有一个具有以下项目结构的 AWS DynamoDb 购物车表 -


  "cart_id": "5e4d0f9f-f08c-45ae-986a-f1b5ac7b7c13",
  "user_id": 1234,
  "type": "OTHER",
  "currency": "INR",
  "created_date": 132432423,
  "expiry": 132432425,
  "total_amount": 90000,
  "total_quantity": 2,  
  "items": [
    
      "amount": 90000,
      "category": "Laptops",
      "name": "Apple MacBook Pro",
      "quantity": 1
    
  ]

-


  "cart_id": "12340f9f-f08c-45ae-986a-f1b5ac7b1234",
  "user_id": 1234,
  "type": "SPECIAL",
  "currency": "INR",
  "created_date": 132432423,
  "expiry": 132432425,
  "total_amount": 1000,
  "total_quantity": 2,  
  "items": [
    
      "amount": 1000,
      "category": "Special",
      "name": "Special Item",
      "quantity": 1
    
  ]

该表将以 cart_id 作为主键,user_id 作为索引或 GSI,type 作为索引或 GSI。

我希望能够查询购物车表, 查找具有user_id = 1234 AND type != "SPECIAL" 的项目。我不知道这是否意味着查询 -

--key-condition-expression "user_id = 1234 AND type != 'SPECIAL'" 

我了解无法同时使用多个索引查询 AWS DynamoDb 表, 我遇到了以下问题,它有一个类似的用例,答案是建议创建一个复合键,Querying with multiple local Secondary Index Dynamodb

是否意味着在表格中放入新项目时, 我将需要维护另一列,例如 user_id_type, 其值为1234SPECIAL 并为user_id_type 创建一个索引/ GSI?

示例项目结构 -


  "cart_id": "5e4d0f9f-f08c-45ae-986a-f1b5ac7b7c13",
  "user_id": 1234,
  "type": "OTHER",
  "user_id_type" : "1234OTHER",
  "currency": "INR",
  "created_date": 132432423,
  "expiry": 132432425,
  "total_amount": 90000,
  "total_quantity": 2,  
  "items": [
    
      "amount": 90000,
      "category": "Laptops",
      "name": "Apple MacBook Pro",
      "quantity": 1
    
  ]

参考资料 - 1.Querying with multiple local Secondary Index Dynamodb 2.Is there a way to query multiple hash keys in DynamoDB?

【问题讨论】:

【参考方案1】:

你的假设是正确的。也许你可以在其中添加一个定界符 field1_field2 或散列它们,如果它们中的任何一个的大小太大 hashOfField1_hashOfField2

但是,这意味着您需要花费更多的处理能力。由于 DynamoDB 本身并不支持它。

Composite key in DynamoDB with more than 2 columns?

Dynamodb: query using more than two attributes

有关您的用例的其他信息

KeyConditionExpression 只允许用于哈希键。 你可以把它放在FilterExpression中

Why is there no **not equal** comparison in DynamoDB queries?

【讨论】:

其他人如何使用 KeyConditionExpression 查询表?如果没有新列并在 KeyConditionExpression = "user_id = :user_id and type 'SPECIAL'" 中传递以下内容,我是否能够实现我的用例,KeyConditionExpression 中的属性是否都需要索引? A 添加了有关您的用例的更多信息。希望这会有所帮助【参考方案2】:

这是否意味着在表格中放入新项目时, 我将需要维护另一列,例如 user_id_type, 其值为 1234SPECIAL 并为 user_id_type 创建一个索引/GSI?

答案取决于有多少列(dynamodb 是无模式的,我所说的列是指数据字段)以及您对 2 次往返 到 DB。

您的查询:

     user_id = 1234 AND type != "SPECIAL" 

1- 如果您需要购物车中的所有信息,但对两次往返感到满意:

解决方案:使用 user_id (HASH) 和 type (RANGE) 创建一个 GSI,然后添加 cart_id(基表哈希键)作为投影。 解释:所以,您需要对索引表进行一次查询,以获取给定 user_id 和类型的 cart_id --key-condition-expression "user_id = 1234 AND type != 'SPECIAL'" 那么您需要使用结果中的 cart_id(s) 并对基表进行另一个查询

2- 如果您不需要所有购物车信息

解决方案:您需要创建一个 GSI 并将 user_id 设为 HASH 并键入 RANGE 并将更多列(您需要的列)添加到投影中。 说明:投影是您希望在索引表中具有的附加列。因此,添加一些额外的列,这些列更有可能被用作查询的结果,以避免到基表的额外往返 注意:添加过多的额外列会使您的成本翻倍,因为对基表的任何更新都会导致 GSI 表投影字段的更新)

3- 如果您只想往返一次并且需要所有数据

那你需要自己管理,你的建议可以采纳

【讨论】:

【参考方案3】:

一个可能的答案是使用排序键创建单个索引。然后你可以这样做:


  TableName: "...",
  IndexName: "UserIdAndTypeIndex",
  KeyConditionExpression: "user_id = :user_id AND type != :type",
  ExpressionAttributeValues: 
    ":user_id": 1234,
    ":type": "SPECIAL"
  

【讨论】:

以上是关于如何使用多个索引查询 AWS DynamoDB?的主要内容,如果未能解决你的问题,请参考以下文章

DynamoDB - 如何计算查询的读取吞吐量

并行执行DynamoDB查询(全局二级索引的BatchGetItems)

如何使用 dynamodb aws 中的索引有效地检索记录

如何使用 AWS Lambda 按名称查询 dynamoDB 表

使用aws cli将全局二级索引添加到DynamoDB中的现有表

DynamoDB 如何使用 AWS KMS