【问题标题】:DynamoDB Limit on queryDynamoDB 查询限制
【发布时间】:2020-09-01 15:58:38
【问题描述】:

我对 DynamoDB 上的查询/扫描中的 Limit 有疑问。

我的表有 1000 条记录,对所有记录的查询返回 50 个值,但如果我将 Limit 设为 5,这并不意味着查询将返回前 5 个值,它只是说查询表上的 5 个项目(以任何顺序,所以它们可能是非常旧的项目或新项目),所以我有可能在查询中得到 0 个项目。怎样才能真正得到一个查询的最新 5 项呢?我需要将Limit 设置为 5(数字是示例),因为查询/扫描比这更多的项目会很昂贵。

查询有这个输入

{
  TableName: 'transactionsTable',
  IndexName: 'transactionsByUserId',
  ProjectionExpression: 'origin, receiver, #valid_status, createdAt, totalAmount',
  KeyConditionExpression: 'userId = :userId',
  ExpressionAttributeValues: {
    ':userId': 'user-id',
    ':payment_gateway': 'payment_gateway'
  },
  ExpressionAttributeNames: {
    '#valid_status': 'status'
  },
  FilterExpression: '#valid_status = :payment_gateway',
  Limit: 5
}

我的表的索引是这样的:

我是否应该使用第二个索引或其他东西,使用字段createdAt 对它们进行排序,但是,我如何确定查询将查看所有项目?

【问题讨论】:

    标签: amazon-dynamodb dynamodb-queries


    【解决方案1】:

    如果我设置了 5 的限制,这并不意味着查询将返回前 5 个值,它只是说查询表上的 5 个项目(以任何顺序,所以它们可能是非常旧的项目或新的),所以我有可能在查询中得到 0 个项目。怎样才能真正得到查询的最新5项?

    您的观察是正确的,不幸的是,没有Query 选项或任何其他操作可以保证单个请求中包含 5 个项目。要理解为什么会出现这种情况(这不仅仅是亚马逊方面的懒惰),请考虑以下极端情况:您有一个包含 10 亿个项目的庞大数据库,但执行一个非常具体的查询,其中只有 5 个匹配项目,现在使您希望的请求:“还给我 5 件物品”。这样的请求需要读取 整个 十亿个项目的数据库,然后才能返回任何内容,届时客户端肯定会放弃。所以这不是 DyanmoDB 的Limit 的工作方式。它限制了 DyanamoDB 在响应之前需要做的工作量。因此,如果Limit = 100,DynamoDB 将在内部读取 100 个项目,这需要有限的时间。但是你是对的,你不知道它是否会响应 100 个项目(如果它们都匹配过滤器)或 0 个项目(如果它们都不匹配过滤器)。

    因此,要高效地做您想做的事,您需要考虑一种不同的方法来为您的数据建模 - 即如何组织分区和排序键。有不同的方法可以做到这一点,每种方法都有自己的优点和缺点,您需要自己考虑选择。既然您询问了 GSI,我将给您一些有关如何使用该选项的提示:

    您要查找的模式称为filtered data retrieval。正如您所指出的,如果您使用排序键为createdAt 执行 GSI,您可以首先检索最新的项目。但是您仍然需要进行过滤,并且仍然不知道如何在 5 个过滤结果(而不是 5 个预过滤)结果后停止。解决方案是要求 DynamoDB 首先仅将通过过滤的项目放入 GSI。在您的示例中,您似乎总是使用相同的过滤器:“status = payment_gateway”。 DynamoDB 在构建 GSI 时没有运行通用过滤器功能的选项,但它有一个不同的技巧来实现相同的目的:任何时候设置“status = payment_gateway”时,还要设置另一个属性“status_payment_gateway” ,并且当状态设置为其他值时,删除“status_payment_gateway”。现在,使用“status_payment_gateway”作为分区键创建 GSI。 DynamoDB 只会将具有此属性的项目放入 GSI 中,从而完全实现您想要的过滤。

    您还可以通过将分区键属性设置为多个不同的值,在一个 GSI 中拥有多个互斥过滤条件,然后您可以分别对每个值执行 Query(使用 KeyConditionExpression)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多