【问题标题】:Dynamodb query expressionDynamodb 查询表达式
【发布时间】:2017-07-14 16:36:20
【问题描述】:

团队,

我有一个带有给定哈希键(用户 ID)和排序键(年龄)的 dynamodb。假设我们想将元素检索为“每个 hashkey(userid),最小年龄”输出,那么 dynamo 查询的查询和过滤器表达式是什么。

谢谢!

【问题讨论】:

    标签: amazon-dynamodb


    【解决方案1】:

    我认为你不能在查询中做到这一点。您需要进行全表扫描。如果您在某处有哈希键列表,那么您可以执行 N 个查询(并行)。

    [更新] 这是另一种可能的方法: 维护第二个表,其中只有一个哈希键 (userID)。该表将包含给定用户年龄最小的记录。为此,请确保每次更新主表时,如果新年龄小于第二个表中的当前年龄,则还更新第二个表。您可以为此使用条件更新。更新可以由应用程序本身完成,也可以让 AWS lambda 监听 dynamoDB 流。现在如果你每次使用都需要最小年龄,你仍然对第二个表进行全表扫描,但是这个扫描只会读取相关记录,它会是最优的。

    【讨论】:

    • 使用 dynamodb 实现这类用例的最佳方法是什么?假设哈希键没有存储在某个地方。
    • 我已经用一种可能的方法更新了我的答案。还有其他的。
    【解决方案2】:

    有两种方法可以实现:

    如果您不需要实时获取这些数据,您可以将数据导出到其他 AWS 系统,例如 EMRRedshift,并在那里执行复杂的分析查询。有了它,您可以使用连接和分组运算符编写 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。而如果您使用流,您将以非常低的价格获得一致的数据。

    【讨论】:

      【解决方案3】:

      您可以使用 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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多