Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services GSI上查询之间的DynamoDB未按预期工作_Amazon Web Services_Nosql_Amazon Dynamodb_Dynamodb Queries - Fatal编程技术网

Amazon web services GSI上查询之间的DynamoDB未按预期工作

Amazon web services GSI上查询之间的DynamoDB未按预期工作,amazon-web-services,nosql,amazon-dynamodb,dynamodb-queries,Amazon Web Services,Nosql,Amazon Dynamodb,Dynamodb Queries,这是一个jobsposts模式,其中一个属性是posted_日期。目标是查询两个日期之间的所有职位。 以下是供您参考的模式: { 'job_id': {S: jobInfo.job_id}, 'company': {S: jobInfo.company}, 'title': {S: jobInfo.title}, 'posted_on': {S: jobInfo.posted_on}, } posted\u on”基于ISO字符串(2019-11-10T10:52:38.013

这是一个jobsposts模式,其中一个属性是posted_日期。目标是查询两个日期之间的所有职位。 以下是供您参考的模式:

{
  'job_id': {S: jobInfo.job_id},
  'company': {S: jobInfo.company},
  'title': {S: jobInfo.title},
  'posted_on': {S: jobInfo.posted_on},
}
posted\u on
”基于ISO字符串(
2019-11-10T10:52:38.013Z
job_id是主键(分区键),由于我需要查询日期,我在发布的上创建了GSI
分区键
)。现在是查询:

  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
}
{
    "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
}
我不知道上面的问题是什么

汤米回答后更新: 我删除了posted\u on上的GSI,并使用作业id作为
分区键和posted\u on作为
排序键重新创建了表。我得到以下错误:

{
    "message": "Query key condition not supported",
    "code": "ValidationException",
    "time": "2019-11-11T06:15:37.231Z",
    "requestId": "J078NON3L8KSJE5E8I3IP9N0IBVV4KQNSO5AEMVJF66Q9ASUAAJG",
    "statusCode": 400,
    "retryable": false,
    "retryDelay": 12.382362030893768
}
{
    "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
}

根据,GSI应该能够使用BETWEEN关键字查询日期。

我想这有点违反直觉,但DynamoDB只支持分区键属性的
.eq
条件

依照

必须提供索引分区键名称和值作为EQ条件。您可以选择提供第二个条件,引用索引排序键

此外,在中,您可以找到以下内容

该条件必须对单个分区键值执行相等测试

该条件可以选择性地对单个排序键值执行多个比较测试之一。这允许查询检索具有给定分区键值和排序键值的一个项,或者检索具有相同分区键值但不同排序键值的多个项

这就解释了您收到的错误消息

解决方案之一可能是创建一个复合主键,将
posted\u on
属性作为排序键,而不是GSI。然后,根据您的用例和访问模式,您需要找出哪个属性最适合作为分区键

应帮助您为架构选择正确的分区键。

与分区键具有特定值且排序键位于给定范围内的查询相关。从status=Z且日期在X和Y之间的表中选择*非常方便。如果我没看错你的问题,那不是你想做的。您需要
从日期介于X和Y之间的表中选择*
。使用DynamoDB查询无法做到这一点-不能按范围查询分区键

如果知道查询日期的最大范围在给定的日期,则可以创建一个分区,分区键设置为日期/时间的计算YYYYMMDD值,其排序键为完整日期/时间。然后,您可以使用键条件表达式查询计算出的YYYYMMDD的分区键以及X和Y之间的排序键。要使其工作,X和Y的YYYYMMDD必须相同


如果您知道查询日期的最大范围是一个月,那么您可以创建一个GSI,分区键设置为日期/时间的计算YYYYMM,其排序键为完整日期/时间。要想让它起作用,X和Y的YYYYMM必须相同。

谢谢@tommy的回答。那么,您的意思是,在将posted_作为排序键后,您应该使用仍在查询中的job_id?如果是这样,那就不是我的用例:(我已经更新了答案。是的,您需要在查询中使用整个主键,包括散列键和排序键。请注意,在您在更新的问题中链接的示例中,GSI也使用复合主键(
status
作为分区键和
createdDateTime
作为排序键)它们都用于查询。当然,您可以使用复合主键创建GSI,例如:
company
作为分区键,
posted\u
作为排序键。并将
job\u id
作为主键保留在原始表中。这一切取决于您的访问模式和用例。嘿,Tommy,我认为您是对的。不w、 我改为扫描,它按预期工作,但效率很低。但我不明白重点。我想要开始日期和结束日期之间的所有作业。我如何提供作业id、分区id?我的数据建模是否错误?无论是简单主键还是复合主键,都必须提供特定的分区键。如果要使用<代码>查询
无需转到特定项目(由分区键标识),您必须使用排序键,但仍然需要提供特定的分区键。(“仅
.eq
支持的条件”部分来自我的答案)。否则,您可以使用
scan
及其所有缺点,这是正确的。查看此博客,也许它会给您一些选择主键的想法。@LakshmanDiwaakar除了我之前的评论外,我还更新了答案。这意味着您需要在每次查询主键范围时创建GSI特定时间范围内的项目。虽然可能,但我认为动态创建GSI以对其运行查询并不实际,特别是考虑到构建GSI所需的时间。我猜您可以每月运行一次任务,为每个月创建一个新的GSI。但是从成本角度来看(如果不是其他方面的话),这将是次优的。您在任何地方见过这种技术吗?我不会动态创建GSI,我会将它作为一个维护索引,投影回答此查询所需的属性。有关DynamoDB和日期范围的一些资源:。