如何仅通过 DynamoDB 中组合键的一部分进行查询?

Vih*_*ung 6 amazon-dynamodb dynamodb-queries

比方说,我正在User写 s 的评论Product

用户和产品是具有自己的 id 的独立实体。

Review是一个实体,其复合 id 由userId和组成productId

我在 DynamoDB 中创建了一个表review,其中userIdproductId作为哈希键。

aws dynamodb create-table --table-name review \
  --attribute-definitions \
      AttributeName=user_id,AttributeType=S \
      AttributeName=product_id,AttributeType=S \
  --key-schema \
      AttributeName=user_id,KeyType=HASH \
      AttributeName=product_id,KeyType=RANGE \
  --provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 
Run Code Online (Sandbox Code Playgroud)

从而形成userId+productId复合键。

评论数据对象是根据该密钥保存的。

查询用户和产品的评论是可以的。

但是如何查询用户的所有评论或产品的所有评论呢?

"#user_id = :userId"使用单个参数,例如,如果我通过单键条件表达式使用 just或 just 进行查询"#product_id = :productId"

我收到表格错误

Query condition missed key schema element: user_id
Run Code Online (Sandbox Code Playgroud)

或者

Query condition missed key schema element: product_id
Run Code Online (Sandbox Code Playgroud)

Set*_*gan 11

我在 DynamoDB 中创建了一个表审核,其中 userId 和 ProductId 作为 HASH 键。

您已为评论表创建了一个复合主键,其中包含一个分区键userId和一个排序键 'productId' 。您没有创建两个 HASH 键。

从逻辑上讲,您的评论表将如下所示(为了说明目的,我编造了一些数据):

审查表

这种表结构可以很容易地获取用户的评论。这是查询所有评论的示例USER#ABC

ddbClient.query(
  "TableName": "<YOUR TABLE NAME>",
  "KeyConditionExpression": "#userId = :userId",
  "ExpressionAttributeValues": {
    ":userId": {
      "S": "USER#ABC"
    }
  },
  "ExpressionAttributeNames": {
    "#userId": "userId"
  }
)

Run Code Online (Sandbox Code Playgroud)

这将返回由 USER#ABC 审阅的项目集合。

DynamoDB 不允许通过指定排序键(例如productId)来获取项目。您始终需要提供分区键。那么如何获得评论过给定产品的用户列表呢?

如果您想搜索评论过单个产品的所有用户,您可以引入一个全局二级索引来交换表的分区键和排序键。这种模式称为倒排索引。使用上面的示例,倒排索引将如下所示:

按产品 ID 划分的全球二级索引

这将允许您通过 ProductId 获取用户:

ddbclient.query(
{
  "TableName": "<YOUR TABLE NAME>",
  "IndexName": "reviews_by_product_index",
  "KeyConditionExpression": "#productId = :productId",
  "ExpressionAttributeValues": {
    ":productId": {
      "S": "PRODUCT#456"
    }
  },
  "ExpressionAttributeNames": {
    "#productId": "productId"
  }
}
)
Run Code Online (Sandbox Code Playgroud)

此查询将返回代表 的评论的两个项目的集合PRODUCT#456

使用复合主键时,只要指定分区键,就可以根据排序键的条件进行搜索。这有点拗口,但它允许您执行类似(伪代码)的查询

查询其中分区键=“USER#ABC”且排序键begins_with“Product”