【发布时间】:2017-07-14 16:36:20
【问题描述】:
团队,
我有一个带有给定哈希键(用户 ID)和排序键(年龄)的 dynamodb。假设我们想将元素检索为“每个 hashkey(userid),最小年龄”输出,那么 dynamo 查询的查询和过滤器表达式是什么。
谢谢!
【问题讨论】:
标签: amazon-dynamodb
团队,
我有一个带有给定哈希键(用户 ID)和排序键(年龄)的 dynamodb。假设我们想将元素检索为“每个 hashkey(userid),最小年龄”输出,那么 dynamo 查询的查询和过滤器表达式是什么。
谢谢!
【问题讨论】:
标签: amazon-dynamodb
我认为你不能在查询中做到这一点。您需要进行全表扫描。如果您在某处有哈希键列表,那么您可以执行 N 个查询(并行)。
[更新] 这是另一种可能的方法: 维护第二个表,其中只有一个哈希键 (userID)。该表将包含给定用户年龄最小的记录。为此,请确保每次更新主表时,如果新年龄小于第二个表中的当前年龄,则还更新第二个表。您可以为此使用条件更新。更新可以由应用程序本身完成,也可以让 AWS lambda 监听 dynamoDB 流。现在如果你每次使用都需要最小年龄,你仍然对第二个表进行全表扫描,但是这个扫描只会读取相关记录,它会是最优的。
【讨论】:
有两种方法可以实现:
如果您不需要实时获取这些数据,您可以将数据导出到其他 AWS 系统,例如 EMR 或 Redshift,并在那里执行复杂的分析查询。有了它,您可以使用连接和分组运算符编写 SQL 表达式。
您甚至可以对 DynamoDB 数据执行 EMR Hive 查询,但它们会执行扫描,因此成本效率不高。
另一个选项是使用 DynamoDB 流。您可以维护一个单独的表来存储:
表:MinAges
UserId - 主键
MinAge - 常规数字属性
在原始查询的每次更新/删除/插入时,您都可以查询更新用户的最小年龄并存储到 MinAges 表中
另一种选择是这样写:
storeNewAge(userId, newAge)
def smallestAge = getSmallestAgeFor(userId)
storeSmallestAge(userId, smallestAge)
但由于 DynamoDB 不支持原生事务,因此运行这样的代码很危险,因为您最终可能会得到不一致的数据。您可以使用DynamoDB transactions library,但这些事务are expensive。而如果您使用流,您将以非常低的价格获得一致的数据。
【讨论】:
您可以使用 ScanIndexForward 来做到这一点
YourEntity requestEntity = new YourEntity();
requestEntity.setHashKey(hashkey);
DynamoDBQueryExpression<YourEntity> queryExpression = new DynamoDBQueryExpression<YourEntity>()
.withHashKeyValues(requestEntity)
.withConsistentRead(false);
equeryExpression.setIndexName(IndexName); // if you are using any index
queryExpression.setScanIndexForward(false);
queryExpression.setLimit(1);
【讨论】: