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

How do I query by only part of a composite key in DynamoDB?

比方说,我有 User 人在写 Product 人的评论。

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

Review 是一个实体,其复合 id 由 userIdproductId.

组成

我在 DynamoDB 中创建了一个 table review,其中 userIdproductId 作为 HASH 键。

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 

从而使userId+productId成为组合键。

评论数据对象是针对该键的。

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

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

使用单个参数,例如如果我只使用 "#user_id = :userId""#product_id = :productId"

通过单键条件表达式进行查询

我收到一个表格错误

Query condition missed key schema element: user_id

Query condition missed key schema element: product_id

I have created a table review in DynamoDB with both userId and productId as HASH keys.

您已经为审核创建了一个复合主键 table,它由 userId 的分区键和 'productId' 的排序键组成。您没有创建两个哈希键。

从逻辑上讲,您的评论 table 看起来像这样(为了说明目的,我编造了一些数据):

这种 table 结构使用户可以轻松获取评论。以下是 USER#ABC

的所有评论的查询示例
ddbClient.query(
  "TableName": "<YOUR TABLE NAME>",
  "KeyConditionExpression": "#userId = :userId",
  "ExpressionAttributeValues": {
    ":userId": {
      "S": "USER#ABC"
    }
  },
  "ExpressionAttributeNames": {
    "#userId": "userId"
  }
)

这将 return USER#ABC 评论的项目集合。

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

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

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

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

此查询将 return 代表对 PRODUCT#456 的评论的两个项目的集合。

使用复合主键时,您可以根据排序键的条件进行搜索,只要您还指定分区键。那是一口,但它允许您执行查询,如(在伪代码中)

query where partition key = "USER#ABC" and sort key begins_with "PRODUCT"