GSI 上的 DynamoDB Between 查询无法按预期工作
DynamoDB Between query on GSI does not work as expected
它是一个 jobPosts 模式,其中一个属性是 posted_date。目标是查询两个日期之间的所有职位发布。
这是供您参考的架构:
{
'job_id': {S: jobInfo.job_id},
'company': {S: jobInfo.company},
'title': {S: jobInfo.title},
'posted_on': {S: jobInfo.posted_on},
}
posted_on
' 基于 ISO 字符串 (2019-11-10T10:52:38.013Z
)。 job_id 是主键(分区键),因为我需要查询日期,所以我创建了 GSI(partition key
) posted_on。现在这里是查询:
const params = {
TableName : "jobPosts",
IndexName: 'date_for_filter_purpose-index',
ProjectionExpression:"job_id, company, title, posted_on",
KeyConditionExpression: "posted_on BETWEEN :startDate AND :endDate",
ExpressionAttributeValues: {
":startDate": {S: "2019-10-10T10:52:38.013Z"},
":endDate": {S: "2019-11-10T10:52:38.013Z"}
}
};
我在 dynamoDB 中有一个文档,这里是:
{
job_id:,
company: "xyz",
title: "abc",
posted_on: "2019-11-01T10:52:38.013Z"
}
现在,执行此操作时,出现以下错误:
{
"message": "Query key condition not supported",
"code": "ValidationException",
"time": "2019-11-11T06:15:37.231Z",
"requestId": "J078NON3L8KSJE5E8I3IP9N0IBVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 12.382362030893768
}
我不知道上面的查询有什么问题。
汤米回答后更新:
我删除了 posted_on 上的 GSI,并用 job_id 重新创建了 table 作为 partition key
和 posted_on 作为 sort key
。我收到以下错误:
{
"message": "Query condition missed key schema element: job_id",
"code": "ValidationException",
"time": "2019-11-12T11:01:48.682Z",
"requestId": "M9E793UQNJHPN5ULQFJI2NR0BVVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 42.52613025785952
}
根据 this SO answer,GSI 应该能够使用 BETWEEN 关键字查询日期。
我想这有点违反直觉,但 DynamoDB 仅支持分区键属性的 .eq
条件。
You must provide the index partition key name and value as an EQ condition. You can optionally provide a second condition, referring to the index sort key.
此外,在Query API Documentation中您可以找到以下内容
The condition must perform an equality test on a single partition key value.
The condition can optionally perform one of several comparison tests on a single sort key value. This allows Query to retrieve one item with a given partition key value and sort key value, or several items that have the same partition key value but different sort key values.
这解释了您收到的错误消息。
其中一个解决方案可能是创建一个复合主键,使用 posted_on
属性作为排序键,而不是 GSI。然后,根据您的用例和访问模式,您需要确定哪个属性最适合作为分区键。
This blog 应该可以帮助您为架构选择正确的分区键。
answer you refer to 与分区键具有特定值且排序键在给定范围内的查询相关。它类似于 select * from table where status=Z and date between X and Y
。如果我没看错你的问题,那不是你想要做的。你想要select * from table where date between X and Y
。您不能使用 DynamoDB 查询执行此操作 - 您不能按范围查询分区键。
如果您知道查询日期的最大范围是在给定的一天,那么您可以创建一个 GSI,并将分区键设置为 date/time 的计算 YYYYMMDD 值及其排序关键是完整的 date/time。然后,您可以使用键条件表达式查询计算出的 YYYYMMDD 的分区键以及 X 和 Y 之间的排序键。为此,X 和 Y 的 YYYYMMDD 必须相同。
如果您知道查询日期的最大范围是一个月,那么您可以创建一个 GSI,并将分区键设置为 date/time 的计算 YYYYMM,并且其排序键是完整的 date/time.为此,X 和 Y 的 YYYYMM 必须相同。
它是一个 jobPosts 模式,其中一个属性是 posted_date。目标是查询两个日期之间的所有职位发布。 这是供您参考的架构:
{
'job_id': {S: jobInfo.job_id},
'company': {S: jobInfo.company},
'title': {S: jobInfo.title},
'posted_on': {S: jobInfo.posted_on},
}
posted_on
' 基于 ISO 字符串 (2019-11-10T10:52:38.013Z
)。 job_id 是主键(分区键),因为我需要查询日期,所以我创建了 GSI(partition key
) posted_on。现在这里是查询:
const params = {
TableName : "jobPosts",
IndexName: 'date_for_filter_purpose-index',
ProjectionExpression:"job_id, company, title, posted_on",
KeyConditionExpression: "posted_on BETWEEN :startDate AND :endDate",
ExpressionAttributeValues: {
":startDate": {S: "2019-10-10T10:52:38.013Z"},
":endDate": {S: "2019-11-10T10:52:38.013Z"}
}
};
我在 dynamoDB 中有一个文档,这里是:
{
job_id:,
company: "xyz",
title: "abc",
posted_on: "2019-11-01T10:52:38.013Z"
}
现在,执行此操作时,出现以下错误:
{
"message": "Query key condition not supported",
"code": "ValidationException",
"time": "2019-11-11T06:15:37.231Z",
"requestId": "J078NON3L8KSJE5E8I3IP9N0IBVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 12.382362030893768
}
我不知道上面的查询有什么问题。
汤米回答后更新:
我删除了 posted_on 上的 GSI,并用 job_id 重新创建了 table 作为 partition key
和 posted_on 作为 sort key
。我收到以下错误:
{
"message": "Query condition missed key schema element: job_id",
"code": "ValidationException",
"time": "2019-11-12T11:01:48.682Z",
"requestId": "M9E793UQNJHPN5ULQFJI2NR0BVVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 42.52613025785952
}
根据 this SO answer,GSI 应该能够使用 BETWEEN 关键字查询日期。
我想这有点违反直觉,但 DynamoDB 仅支持分区键属性的 .eq
条件。
You must provide the index partition key name and value as an EQ condition. You can optionally provide a second condition, referring to the index sort key.
此外,在Query API Documentation中您可以找到以下内容
The condition must perform an equality test on a single partition key value.
The condition can optionally perform one of several comparison tests on a single sort key value. This allows Query to retrieve one item with a given partition key value and sort key value, or several items that have the same partition key value but different sort key values.
这解释了您收到的错误消息。
其中一个解决方案可能是创建一个复合主键,使用 posted_on
属性作为排序键,而不是 GSI。然后,根据您的用例和访问模式,您需要确定哪个属性最适合作为分区键。
This blog 应该可以帮助您为架构选择正确的分区键。
answer you refer to 与分区键具有特定值且排序键在给定范围内的查询相关。它类似于 select * from table where status=Z and date between X and Y
。如果我没看错你的问题,那不是你想要做的。你想要select * from table where date between X and Y
。您不能使用 DynamoDB 查询执行此操作 - 您不能按范围查询分区键。
如果您知道查询日期的最大范围是在给定的一天,那么您可以创建一个 GSI,并将分区键设置为 date/time 的计算 YYYYMMDD 值及其排序关键是完整的 date/time。然后,您可以使用键条件表达式查询计算出的 YYYYMMDD 的分区键以及 X 和 Y 之间的排序键。为此,X 和 Y 的 YYYYMMDD 必须相同。
如果您知道查询日期的最大范围是一个月,那么您可以创建一个 GSI,并将分区键设置为 date/time 的计算 YYYYMM,并且其排序键是完整的 date/time.为此,X 和 Y 的 YYYYMM 必须相同。