【问题标题】:How to query dynamodb table using gte comparison operator如何使用 gte 比较运算符查询 dynamodb 表
【发布时间】:2014-09-26 20:07:57
【问题描述】:

我有一个简单的 dynamodb2 表,其中包含 task_names(字符串)及其开始时间(数字/浮点数)。如何获取开始时间大于给定数字 X 的所有记录? 目前,我尝试将开始时间作为全局二级索引并使用以下内容:

table hashkey 是 task_name,range key 是开始时间。 我在 start_time (start_time-index) 上做了一个二级全局索引,并用它来查询下面。

recs =tab.query(start_time__gte=1, index='start_time-index')

但是,它说:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/nail/home/osarood/work/.venv/local/lib/python2.7/site-packages/boto/dynamodb2/results.py", line 62, in __next__
    self.fetch_more()
  File "/nail/home/osarood/work/.venv/local/lib/python2.7/site-packages/boto/dynamodb2/results.py", line 146, in fetch_more
    results = self.the_callable(*args, **kwargs)
  File "/nail/home/osarood/work/.venv/local/lib/python2.7/site-packages/boto/dynamodb2/table.py", line 1132, in _query
    **kwargs
  File "/nail/home/osarood/work/.venv/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 1522, in query
    body=json.dumps(params))
  File "/nail/home/osarood/work/.venv/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 2100, in make_request
    retry_handler=self._retry_handler)
  File "/nail/home/osarood/work/.venv/local/lib/python2.7/site-packages/boto/connection.py", line 937, in _mexe
    status = retry_handler(response, i, next_sleep)
  File "/nail/home/osarood/work/.venv/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 2140, in _retry_handler
    response.status, response.reason, data)
boto.dynamodb2.exceptions.ValidationException: ValidationException: 400 Bad Request
{u'message': u'Query key condition not supported', u'__type': u'com.amazon.coral.validate#ValidationException'}

【问题讨论】:

  • 你的start_time属性是什么类型的?
  • 它是一个数字。基本上是纪元时间。

标签: amazon-dynamodb boto


【解决方案1】:

(已编辑 - 查看原始错误答案的修订历史记录)

您收到错误的原因是您没有为查询指定哈希键 - you must include the hash key attribute name and value as an EQ condition

为了解决这个问题,有几个选择:

如果您在执行范围查询时知道任务名称,则不需要 GSI;只需在带有 EQ 条件的查询中包含 taskName。

如果您不知道任务名称,GSI 可以解决此问题是正确的,但它的工作方式存在局限性。使用 GSI 时要记住的是,它们基本上也只是表,但它们是由 Dynamo 维护的。因此,它们还需要一个 hashkey 和 rangekey 来指定唯一性。

  • 要在没有任务名称的情况下进行查询,您将需要一个备用哈希键 - 为简单起见,我建议使用类似于 this one 的方法:
    • 创建一个 GSI,哈希键为 YearMonth(例如,201508)和范围键 timestamp+taskName(将 taskName 附加到 GSI 范围键的原因是为了确保 GSI 中哈希键/范围键组合的正确唯一性)
    • 多次查询 GSI,每个月查询一次。查询也按范围键 timestamp &gt; [given timestamp] 过滤。
    • 这种方法的一个缺点是,如果您要快速创建大量任务,您可能会在 YearMonth 有一个热哈希键,这会影响您的表吞吐量 - this answer 有处理时间序列数据的更多提示:
    • 使 GSI 哈希键更加细化
    • 使用可能具有不同 hashkey 粒度的不同表(根据日期范围生成的表名)来管理热/冷数据

作为最后的手段,考虑使用全表扫描(这是最后的手段,因为它确实会影响您的吞吐能力)

【讨论】:

  • 添加范围键(可能)在这里无济于事。如您的回答中所述,范围键仅在您查询具有已知哈希键的条目时才有用。因此,除非事先知道所有哈希键(在本例中为任务名称),否则不能仅通过 start_time 进行查询。
  • @jonson - 非常正确。我不知道我在写这篇文章时在想什么。有趣的是 OP 接受了它,这阻止了我删除它。请随时进行更正以使其有用。
  • @jonson - 我已经大幅更新了答案。如果您有进一步的编辑建议,我愿意接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
  • 2020-03-14
  • 2017-10-25
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多