简体   繁体   English

DynamoDB QueryResultPage 仍然在虚假的独占启动键上返回结果

[英]DynamoDB QueryResultPage still returning results on bogus exclusive start key

tldr; tldr; - When using a bogus LastEvaluatedKey with DynamoDB queries for pagination it still returns results in some cases. - 当使用虚假 LastEvaluatedKey 和 DynamoDB 查询进行分页时,它在某些情况下仍会返回结果。

I am implementing pagination for a fairly straight forward CRUD Repository.我正在为一个相当直接的 CRUD 存储库实现分页。 The implementation is based on: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.Pagination.html and实施基于: https : //docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.Pagination.html
Pagination with DynamoDBMapper Java AWS SDK 使用 DynamoDBMapper Java AWS SDK 进行分页

I have a DynamoDB table and this query is running on a Global Secondary Index of that table.我有一个 DynamoDB 表,该查询正在该表的全局二级索引上运行。

Pagination is working fine, ie I have a 5000 records.分页工作正常,即我有 5000 条记录。 I query and receive a set of 500 results and a LastEvaluatedKey.我查询并收到一组 500 个结果和一个 LastEvaluatedKey。 Using this key, I get the next set of 500 results etc.使用这个键,我得到下一组 500 个结果等。

This key is made up of:该密钥由以下部分组成:

  • partition key "instanceId" which is always the same on subsequent page requests.分区键“instanceId”在后续页面请求中始终相同。
  • range key "id" which is what changes on the next page request范围键“id”,这是下一页请求的变化

Now I wrote a test to make sure that if a bogus LastEvaluatedKey is provided I should get zero results.现在我写了一个测试来确保如果提供了一个虚假的 LastEvaluatedKey 我应该得到零结果。

What is the actual behavior:实际行为是什么:

If I provide something like id = "rrrrrrrrrrrrr" I get zero results, as expected.如果我提供类似 id = "rrrrrrrrrrrrrr" 的内容,我会得到零结果,正如预期的那样。
If I provide something like id = "aaaaaaaaaaaaa" I get 500 results!如果我提供类似 id = "aaaaaaaaaaaaa" 的内容,我会得到 500 个结果!

What's worth noting is that the "id"'s are UUID strings, so the letter 'r' will not occur anywhere in any id.值得注意的是,“id”是 UUID 字符串,因此字母“r”不会出现在任何 id 中的任何位置。

My LastEvaluatedKey is made up like so (instanceId is the same for subsequent page queries):我的 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);

I suspect what is happening is that because "id" is a sort key (in the GSI), the results are returned for anything greater than my bogus "aaaaaaaaaaaaaa".我怀疑正在发生的事情是因为“id”是一个排序键(在 GSI 中),结果返回的结果大于我的虚假“aaaaaaaaaaaaaa”。 For "rrrrrrrrrrrr" it doesn't work because no keys would sort greater than 'rrrrrrrrrrrr'.对于“rrrrrrrrrrrrr”,它不起作用,因为没有键的排序大于“rrrrrrrrrrrrr”。

I would expect DDB to match exactly the exclusive start key, and return the next set of results from there but it seems like it is simply matching whatever comes close and returning whatever keys come after.我希望 DDB 与唯一的开始键完全匹配,并从那里返回下一组结果,但它似乎只是匹配接近的任何东西并返回后面的任何键。

I also found: DynamoDB Global Secondary Index with Exclusive Start Key我还发现: DynamoDB Global Secondary Index with Exclusive Start Key

In there the solution is to set the primary and range keys of both the table and the index as the ExclusiveStartKey.在那里,解决方案是将表和索引的主键和范围键设置为 ExclusiveStartKey。 However, in my case both are there, they are just reversed:但是,就我而言,两者都在那里,它们只是颠倒了:

On the table the id is primary, instanceId is secondary.在表上,id 是主要的,instanceId 是次要的。 On the GSI, the reverse is true.在 GSI 上,情况正好相反。

Can someone explain what is happening or what I'm doing wrong?有人可以解释发生了什么或我做错了什么吗?

Working as designed...按设计工作...

ExclusiveStartKey just means to start with key greater than whatever value you've passed in. ExclusiveStartKey只是意味着以大于您传入的任何值的键开始。

Exclusive, meaning use greater than as opposed to inclusive which would be greater than or equal.独占,意味着使用大于,而不是大于或等于的包含。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM