我正在使用 AWS 托管 API 网关和 DynamoDB 直接集成的 API。
我现在正在尝试为我的应用程序添加分页功能,但我很难 100% 实现它。
我面临的问题是当我向后扫描时,我会给你一个例子来更好地理解这个问题。
想象一下,我有一个包含 20 个项目的列表,页面大小为 5。
1, 2, 3, 4, 5
。预期行为! 6, 7, 8, 9, 10
。预期行为。 ScanIndexForward=false
进行查询时,我的问题就出现了。这意味着我不想继续前进。相反,我想要 lastEvaluatedKey
中的先前项目。问题是,如果我使用从上次查询中检索到的 lastEvaluatedKey
,而不是像 5, 4, 3, 2, 1
那样的东西,我有 4, 3, 2, 1
。 lastEvaluatedKey
中的元素或根据需要将其称为 head
的元素将被跳过。如果你想象一个表中的正常行为,你点击
next page
和 previous 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/