DynamoDB 中的 PaginatedQueryList 和 QueryResultPage 有什么区别?

What is the difference between PaginatedQueryList and QueryResultPage in DynamoDB?

我目前正在使用 Java 和 DynamoDBMapper 使用 DynamoDB。我看到当我们使用 DynamoDBQueryExpression 时,我们可以使用 PaginatedQueryListQueryResultPage。如果我们使用下面的任何一种方法,我们必须使用,

query method - returns a [PaginatedQueryList][1]
queryPage method - returns a [QueryResultPage][1]

PaginatedQueryList 表示它将首先加载 1MB 的数据,如果我们遍历然后它将在需要时加载下一页并且这也是分页的。但是 QueryResultPage 呢?它说它正在加载 1MB 的数据。但是如果我们迭代它呢?它会加载第二页还是只给我们 1MB 的数据?我找不到任何相关信息?而且 QueryResultPage 给了我们 LastEvaluatedKeyPaginatedQueryList 没有。那么有没有办法在 PaginatedQueryList 中获取 LastEvaluatedKey 或者如果我们需要获取该密钥,我们是否必须始终使用 QueryResultPage?

并且也代替了下面的代码,

PaginatedQueryList<Data> data = dynamoDBMapper.query(Data.class, queryExpression);

如果我们使用下面的,

List<Data> data = dynamoDBMapper.query(Data.class, queryExpression);
data.size();

它会加载在数据库中找到的所有数据吗?如果我使用 stream() 而不是 data.size() 会加载全部吗?

TL;DR:

  • QueryResultPage 不会延迟加载任何其他数据,只有 PaginatedQueryList 会这样做。
  • PaginatedQueryList 为您抽象出分页,这就是它不公开密钥的原因。如果您需要密钥,则需要使用 queryPageQueryResultPage。如果您需要的不仅仅是第一页,您必须自己请求其他页面。
  • .size() 会将所有数据加载到内存中,因为您需要有数据才能对它们进行计数。
  • .stream() 可能会将所有数据加载到内存中,具体取决于您对流执行的操作。如果您说 .stream().limit(1) 则不会加载更多页面。但是如果你说 .stream().count() 那么 所有页面 都会被加载。

查看这 2 个文档,PaginatedQueryList 似乎是一个对象,它试图从你身上抽象出一个事实,即结果下面是分页的。

来自 https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/PaginatedQueryList.html(强调我的):

[...] Paginated results are loaded on demand when the user executes an operation that requires them. Some operations, such as size(), must fetch the entire list, but results are lazily fetched page by page when possible.

所以,如果你基本上不想处理分页,就使用query方法。但请记住,如果您想 return 所有结果(或知道它们的大小)

,您的应用程序最终仍需要翻阅结果

另一方面,QueryResultPage 更接近 DynamoDB API。你正在处理一个页面,你可以使用 getLastEvaluatedKey() to get the parameter to be used for the next setExclusiveStartKey (on your DynamoDBQueryExpression)

总结:

  • query 对用户更友好,因为它隐藏了显式分页,但如果您的结果包含许多页面,您的代码可能会变慢而您一开始没有注意到,因为这些页面是延迟加载的。
  • queryPage 的意图更加明确。您必须手动加载每个页面,因此请考虑您是否真的需要所有数据,或者您是否不想进一步将分页卸载给您的客户端。

你可以在 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html#DynamoDBMapper.Methods.queryPage 阅读 queryPage 的官方文档时看到类似的描述(强调我的):

Queries a table or secondary index and returns a single page of matching results. As with the query method, you must specify a partition key value and a query filter that is applied on the sort key attribute. However, queryPage returns only the first "page" of data, that is, the amount of data that fits in 1 MB