我想使用QuerySpec.withMaxPageSize(int limit)来实现分页。我这样用它:
QuerySpec querySpec = new QuerySpec()
.withKeyConditionExpression("id = :v_id")
.withValueMap(new ValueMap()
.withString(":v_id", "1234"))
.withScanIndexForward(false)
.withMaxPageSize(Integer.parseInt(5));
ItemCollection<QueryOutcome>items = table.query(querySpec);
int startPage = 0;
for (Page<Item, QueryOutcome> page : items.pages()) {
System.out.println("Page: " + ++startPage);
Iterator<Item> iterator = page.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
然后结果是正确的:每个页面都有5个项目。
但是当我像这样使用QuerySpec时:
QuerySpec querySpec = new QuerySpec()
.withKeyConditionExpression("id = :v_id")
.withFilterExpression("eventType = :v_eventType")
.withValueMap(new ValueMap()
.withString(":v_id", "1234")
.withString(":v_eventType", "event"))
.withScanIndexForward(false)
.withMaxPageSize(Integer.parseInt(5));
然后结果完全错误:
Page: 1
{ Item: {id=1234, timestamp=1489480336243, eventType=starRating} }
{ Item: {id=1234, timestamp=1489476430129, eventType=starRating, }
{ Item: {id=1234, timestamp=1489460649642, eventType=starRating, }
Page: 2
{ Item: {id=1234, timestamp=1489137400014, eventType=starRating} }
Page: 3
{ Item: {id=1234, timestamp=1489137294383, eventType=starRating} }
Page: 4
{ Item: {id=1234, timestamp=1489137046331, eventType=starRating} }
Page: 5
{ Item: {id=1234, timestamp=1489137030983, eventType=starRating} }
{ Item: {id=1234, timestamp=1489137022138, eventType=starRating} }
Page: 6
{ Item: {id=1234, timestamp=1489136930427, eventType=starRating} }
Page: 7
{ Item: {id=1234, timestamp=1489136782467, eventType=starRating} }
{ Item: {id=1234, timestamp=1489136765162, eventType=starRating} }
{ Item: {id=1234, timestamp=1489136669765, eventType=starRating} }
Page: 8
{ Item: {id=1234, timestamp=1489136478857, eventType=starRating} }
{ Item: {id=1234, timestamp=1489136453453, eventType=starRating} }
{ Item: {id=1234, timestamp=1489136435202, eventType=starRating} }
{ Item: {id=1234, timestamp=1489136384098, eventType=starRating} }
Page: 9
{ Item: {id=1234, timestamp=1489136253163, eventType=starRating} }
每个页面都有不同的项目。看起来当我添加过滤器表达式时,会出现这个问题。但我不知道为什么。有人知道吗?
答案 0 :(得分:2)
以下是documentation的摘录,解释了为什么每页都会获得不同的行数:
在响应中,DynamoDB返回所有匹配的结果 极限值的范围。例如,如果您发出查询或扫描 请求限制值为6且没有过滤器表达式, DynamoDB返回表中与之匹配的前六项 请求中指定的关键条件(或仅前六项) 在没有过滤器的扫描的情况下)。如果你还提供一个 FilterExpression值,DynamoDB将返回第一个项目 六,也符合过滤要求(结果数量 返回将小于或等于6)。
因此,当您使用FilterExpression和限制查询时,DynamoDB会从表中读取最多Limit
个记录,然后过滤掉与您的FilterExpression
不匹配的记录。
UPD:为了获得每页的确切记录数,您必须使用更复杂的方法。获得第一个查询结果后,如果返回的子集包含少于Limit
项,
将记录保存到缓冲区并继续读取,直到项目总数变为&gt; =限制。如果缓冲区中的记录数超过限制,则丢弃超过记录。
这就是你如何获得第一页的确切大小Limit
项(在你的情况下为5)。
要获取第二页,您可以运行一个提供KeyConditionExpression的新查询
id = :v_id and #timestamp < :timestamp
,并使用:timestamp
上一页的最后一条记录的时间戳值。同样,您必须多次阅读,直到缓冲区中的项目总数变为&gt; =您的首选页面大小。使用相同的方法获取所有后续页面。