java - DynamoDB QueryResultPage 仍然在伪造的独占开始键上返回结果
问题描述
tldr; - 当使用伪造的 LastEvaluatedKey 和 DynamoDB 查询进行分页时,在某些情况下仍会返回结果。
我正在为一个相当直接的 CRUD 存储库实现分页。该实施基于:
https ://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.Pagination.html和
使用 DynamoDBMapper Java AWS SDK的分页
我有一个 DynamoDB 表,并且该查询在该表的全局二级索引上运行。
分页工作正常,即我有 5000 条记录。我查询并收到一组 500 个结果和一个 LastEvaluatedKey。使用这个键,我得到下一组 500 个结果等。
该密钥由以下部分组成:
- 分区键“instanceId”在后续页面请求中始终相同。
- 范围键“id”是下一页请求的变化
现在我编写了一个测试,以确保如果提供了虚假的 LastEvaluatedKey,我应该得到零结果。
实际行为是什么:
如果我提供类似 id = "rrrrrrrrrrrrrr" 的内容,我会得到零结果,正如预期的那样。
如果我提供类似 id = "aaaaaaaaaaaaa" 的内容,我会得到 500 个结果!
值得注意的是,“id”是 UUID 字符串,因此字母 'r' 不会出现在任何 id 的任何位置。
我的 LastEvaluatedKey 是这样组成的(instanceId 与后续页面查询相同):
var startKeyMap = new HashMap<String, AttributeValue>();
var idValue = new AttributeValue();
idValue.setS(startKey);
startKeyMap.put("id", idValue);
var instanceIdValue = new AttributeValue();
instanceIdValue.setS(instanceId);
startKeyMap.put("instanceId", instanceIdValue);
queryExpression.setExclusiveStartKey(startKeyMap);
我怀疑正在发生的事情是因为“id”是一个排序键(在 GSI 中),所以返回的结果大于我的虚假“aaaaaaaaaaaaaa”。对于“rrrrrrrrrrrr”,它不起作用,因为没有键会排序大于“rrrrrrrrrrrr”。
我希望 DDB 能够完全匹配唯一的开始键,并从那里返回下一组结果,但似乎它只是匹配任何接近的东西并返回后面的任何键。
我还发现: DynamoDB Global Secondary Index with Exclusive Start Key
在那里,解决方案是将表和索引的主键和范围键设置为 ExclusiveStartKey。但是,就我而言,两者都存在,它们只是颠倒了:
在表上,id 是主要的,instanceId 是次要的。在 GSI 上,情况正好相反。
有人可以解释发生了什么或我做错了什么吗?
解决方案
按设计工作...
ExclusiveStartKey
只是意味着以大于您传入的任何值的键开始。
独占,意思是使用大于,而不是包含大于或等于。
推荐阅读
- powershell - 如何为所有用户使用 PowerShell 命令“Get-AdminPowerAppsUserDetails”
- node.js - 枚举数组的猫鼬模式
- c++ - C ++ while循环读取ifstream,不会在eof处停止
- ios - 如何在 iMessage 文本选择上下文菜单中添加自定义操作?
- qt - 通过函数调用 id
- python - 将 tkinter 画布形状放在光标位置
- java - 如何选择特定容器的跨度元素(由 CSS 类定义)使用 Xpath?
- flutter - 颤振滑块颜色
- assembly - 将数组 arg 的第一个值移动到 xmm0
- python-3.x - 我应该如何从 data-* 属性中抓取数据?