Amazon dynamodb 当日期是唯一键时,查询日期范围

Amazon dynamodb 当日期是唯一键时,查询日期范围,amazon-dynamodb,dynamodb-queries,Amazon Dynamodb,Dynamodb Queries,我想使用DynamoDB存储历史股票收盘价。 我的商店将会有一些存货,并且随着需求的变化而增加。 我想我将有一个表,其中唯一的键是“DATE”,格式为YYYY-MM-DD 这意味着表中的每个项目都有一个date键和几个{TICKER=CLOSING\u VALUE} 对给定日期的查询也将按所需股票代码的子集进行过滤,例如[“INTC”,“AAPL”] 我有点困惑,因为这个单键应该同时用作分区键和排序键 我应该如何查询以检索给定日期范围的股票报价器子集 更新: 我正在用…创建表格 { Att

我想使用DynamoDB存储历史股票收盘价。 我的商店将会有一些存货,并且随着需求的变化而增加。 我想我将有一个表,其中唯一的键是
“DATE”
,格式为
YYYY-MM-DD

这意味着表中的每个项目都有一个
date
键和几个
{TICKER=CLOSING\u VALUE}

对给定日期的查询也将按所需股票代码的子集进行过滤,例如
[“INTC”,“AAPL”]

我有点困惑,因为这个单键应该同时用作分区键和排序键

我应该如何查询以检索给定日期范围的股票报价器子集


更新:

我正在用…创建表格

{
  AttributeDefinitions: [
    {
      AttributeName: Date,
      AttributeType: S
    }
  ],
  TableName: "Historic",
  KeySchema: [
    {
      AttributeName: Date,
      KeyType: HASH
    }
  ]
}
以及查询:

    {
        table_name: "Historic",
        projection_expression: "USD,CAD",
        filter_expression: "#k between :val1 and :val2",
        expression_attribute_names: { "#k" => "Date" },
        expression_attribute_values: {
            ":val1" => "2019-12-01",
            ":val2" => "2020-01-10"
        }
    }

我得到一个错误:
Aws::DynamoDB::Errors::ValidationException:必须在请求中指定KeyConditions或KeyConditionExpression参数。

您无法按分区键排序或有效地检索分区键的范围,只能按排序键排序。要了解原因,您需要了解DynamoDB如何存储其数据

“分区键”在“散列键”中也被称为“散列键”——实际上它的工作原理类似于散列表中的键:DynamoDB对该键运行一个散列函数,并使用生成的数字决定其大型集群中的哪个节点应持有该分区。这种方法允许在集群中分布表,但它使得不可能有效地检索按键排序的不同分区。“扫描”操作将以看似随机的顺序返回分区(它们很可能按其键的哈希函数排序),并且不可能有效地只扫描一系列分区键。通过扫描整个表并只过滤您想要的分区,这可能会降低效率。如果我理解正确的话,这就是你想要做的。但这只对小型数据库有意义——这是你的情况吗

正如您所注意到的,该键的另一个组件是“排序键”。在一个分区内,在一个节点中,该分区中的不同项按“排序键”顺序进行排序。这使得DynamoDB能够高效地检索按此顺序排序的排序键,或者仅高效地检索这些排序键的一部分,
Query
请求可以完成这两项任务

因此,要实现您想要的,您需要将日期设置为排序键,而不是分区键。如何进行其余的数据建模取决于典型查询的外观:

如果您有大量库存,但典型的查询只要求少量库存,最合理的方法是使用库存名称作为分区键,如我所说,使用数据作为排序键。这将允许您高效地
查询一只特定股票的日期范围-如果您需要3只不同的股票,您将需要执行3次
查询
s(您可以并且应该并行执行!),但每一次查询都是高效的,您只需支付所检索的实际数据,而无需任何后期筛选


如果存在大量不同的日期(例如,将数据保持在1秒的分辨率),则分区可能会变大,出于各种原因,不建议这样做。在这种情况下,您可以通过一些粗略的时间窗口将每个分区拆分为多个分区。例如,不要为股票“GOOG”设置一个巨大的分区,而是设置一个分区“GOOG Nov 2019”,一个分区“GOOG Dec 2019”,等等。当您查询一个小的日期范围时,您将知道需要从哪个特定分区读取。但是当查询跨越一个月以上时,您将需要查询多个分区。请注意,非常大的查询将读取(并返回)大量数据,因此将非常昂贵,因此您可能只希望在大型分析作业中执行此操作。

您应该使用
FilterExpression
谢谢@Alex-我正在使用FilterExpression(或至少正在尝试)。我是dynamoDB新手,所以语法不熟练。另外,我想知道在分区和排序中使用相同的键(日期)是否正确。是的,您可以只使用分区键,尝试这样做,如果遇到问题,请使用附带的代码更新您的问题谢谢Nadav,工作得很有魅力。将股票符号重构为分区向我表明,当涉及到dynamoDB时,我需要以不同的方式思考。仍在研究如何从Ruby执行并行查询。