Dynamodb按排序顺序扫描

Erb*_* Mo 38 amazon-web-services amazon-dynamodb

嗨,我有一个dynamodb表.我希望服务返回此表中的所有项目,顺序是通过对一个属性进行排序.

我是否需要为此创建全局二级索引?如果是这种情况,那么散列键应该是什么,范围键是什么?(注意,对gsi的查询必须在GSI的散列键上指定"EQ"比较器.)

谢谢你的日志!

厄尔本

Son*_*van 21

如果您知道HashKey,那么任何查询都将返回按Range键排序的项:

"查询结果始终按范围键排序.如果范围键的数据类型为Number,则结果以数字顺序返回;否则,结果将按ASCII字符代码值的顺序返回.默认情况下,排序顺序为了反转顺序,请使用ScanIndexForward参数设置为false." 查询和扫描操作 - Amazon DynamoDB:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html

现在,如果您需要返回"所有项目",则表示扫描.我不认为你可以订购扫描结果.

另一种选择是使用GSI.(例如:https://stackoverflow.com/a/21786544/2959100).在这里,您可以看到GSI仅包含HashKey.结果我猜是按照这个键的排序顺序(我还没在程序中查看这个部分!)

  • 该文档将ScanIndexForward描述为仅应用于查询操作,而不是扫描.我没有看到文档说这适用于扫描. (4认同)

Dee*_*moe 10

截至目前,dynamoDB扫描无法返回排序结果。

你需要使用一个查询与一hashkey和范围领域的一个新的全球次级指数(GSI)。诀窍是使用一个哈希键,它为表中的所有数据分配了相同的值

我建议为所有数据创建一个新字段并将其称为“状态”并将值设置为“OK”或类似的值。

然后,您对所有结果进行排序的查询将如下所示:

{
    TableName: "YourTable",
    IndexName: "Status-YourRange-index",
    KeyConditions: {
        Status: {
            ComparisonOperator: "EQ", 
            AttributeValueList: [ 
                "OK"
            ]
        }
    },
    ScanIndexForward: false
}
Run Code Online (Sandbox Code Playgroud)

有关如何编写 GSI 查询的文档可在此处找到:http : //docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.Querying

  • 这是一个可怕的建议。DynamoDB 表的性能特征同样适用于 GSI。具有单个散列键“OK”的 GSI 将只使用一个分区。这会失去 DynamoDB 的所有扩展特性。 (50认同)
  • @prestomation 这不是可怕的建议。确实,它不能很好地扩展。但恰恰相反,考虑到限制(1000 次写入/秒、3000 次读取/秒、10 GB 表大小),它可以维持一个非常划算的解决方案。可怕的建议是盲目遵循最佳实践并远离现实世界的解决方案。 (31认同)
  • 这是真实的结果将来自单个分区,但是如果与限制结合使用,则它可以是有效的。如果您限制为 10 个项目,您将按排序顺序获得前 10 个项目,这不会是一个昂贵的查询。(除了维护第二个 GSI)因此,例如,如果您只想显示列表中的最新项目,则效率很高。 (4认同)
  • 需要注意的一件事是,AWS 处理时间序列数据的最佳实践虽然建议使用多个表以实现更高效的预配置读/写容量,但建议的解决方案对每个表中的每个项目使用相同的分区键:https:// /docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-time-series.html (3认同)
  • 问题的作者没有说他的表中有多少项或他想提供多少读取单元,但看起来即使是单个分区也可以相当轻松地支持 1000 个读取单元,最多可达 3000 个读取单元。来源:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html (2认同)
  • 这在功能上等同于只有 1 个分片的“索引写入共享”。请参阅 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-indexes-gsi-sharding.html (2认同)

Gir*_*esh 5

我遵循的解决此问题的方法是创建如下的全局二级索引。不知道这是否是最好的方法,但是如果对某人有用,则将其发布。

Hash Key                 | Range Key
------------------------------------
Date value of CreatedAt  | CreatedAt
Run Code Online (Sandbox Code Playgroud)

对HTTP API用户的限制,用于指定检索数据的天数,默认为24小时。

这样,我总是可以将HashKey指定为当前日期,并且RangeKey可以在检索时使用>和<运算符。这样,数据也可以分布在多个分片上。

  • 这是[处理时间序列数据的最佳实践](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-time-series.html) 中推荐的模式,它本身是一种 [索引写入分片](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-indexes-gsi-sharding.html)。 (2认同)