我正在使用 AWS 托管 API 网关和 DynamoDB 直接集成的 API。

我现在正在尝试为我的应用程序添加分页功能,但我很难 100% 实现它。
我面临的问题是当我向后扫描时,我会给你一个例子来更好地理解这个问题。

想象一下,我有一个包含 20 个项目的列表,页面大小为 5。

  • 当我查询我的表时,第一个查询将返回 1, 2, 3, 4, 5 。预期行为!
  • 当我查询我的表时,将来自第五个元素的 lastEvaluatedKey 传递给它,它返回 6, 7, 8, 9, 10 。预期行为。
  • 现在,当我使用标志 ScanIndexForward=false 进行查询时,我的问题就出现了。这意味着我不想继续前进。相反,我想要 lastEvaluatedKey 中的先前项目。问题是,如果我使用从上次查询中检索到的 lastEvaluatedKey ,而不是像 5, 4, 3, 2, 1 那样的东西,我有 4, 3, 2, 1
  • lastEvaluatedKey 中的元素或根据需要将其称为 head 的元素将被跳过。

    如果你想象一个表中的正常行为,你点击 next pageprevious page ,这意味着当你转到第二页,然后回到第一页时,你只会得到 4 个项目,而不是一个,对于建议的场景。

    最后,我用 AWS CLI 尝试了相同的查询,结果是一样的。在与支持人员聊天后,他们确认这是预期的行为。

    我只想知道人们如何看待这种情况,因为我知道亚马逊在生产中使用它,所以应该有一种方法可以做到这一点。

    最佳答案

    要理解您所看到的行为,您需要了解 LastEvaluatedKey 的最初目的不是以您想要的方式随机访问查询中间的某个地方 - 而是在查询之后恢复查询在页面边界处停止。考虑到这一点,当 ScanIndexForward=false 假设它正在继续一个正在进行的反向查询时;因此,如果您传递 LastEvaluatedKey=5,它假定先前返回的序列是 10, 9, 8, 7, 6, 5(返回的最后一项是 5) - 所以现在将继续到 4, 3, 2, 1。正如您所指出的。

    如果出于您的目的,您还需要“5”项目,您可以在单独的请求中单独阅读此项目。它不会让您花费更多,因为亚马逊按读取的项目大小向您收费 - 在同一查询中返回多个项目时,它并不便宜。如果您并行执行读取和查询,延迟也不会增加。

    更新:

    正如查尔斯在下面的评论中指出的那样,对于短项目和短页面,对“5”的额外 GetItem 请求实际上会花费你另一个 RCU,这可能很重要,所以这不是一个好主意。

    所以还有另一种选择,那就是根本不使用 LastEvaluatedKey。相反,Query 允许您在 KeyConditionExpression 中不仅指定所需的分区键,还指定一系列排序键。您可以指定范围“sort

    关于amazon-web-services - AWS DynamoDB 向后扫描忽略 LastEvaluatedKey,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58533413/

    10-11 06:41