如何使用gte比较运算符查询dynamodb表

时间:2014-09-26 20:07:57

标签: amazon-dynamodb boto

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

表hashkey是task_name,范围键是开始时间。 我在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'}

1 个答案:

答案 0 :(得分:-2)

(已编辑 - 请参阅原始错误答案的修订历史记录)

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

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

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

如果你不知道任务名称,那么GSI可以解决这个问题是正确的,但它的工作方式有局限性。 GSI要记住的是,它们基本上只是表格,但它们由Dynamo维护在引擎盖下。因此,他们还需要一个hashkey和rangekey来指定唯一性。

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

作为最后的手段,请考虑使用全表扫描(这是最后的手段,因为它会真正影响您的吞吐量)