【问题标题】:What is the difference between PaginatedQueryList and QueryResultPage in DynamoDB?DynamoDB 中的 PaginatedQueryList 和 QueryResultPage 有什么区别?
【发布时间】:2021-07-30 15:33:38
【问题描述】:

我目前正在使用带有 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() 会加载所有内容吗?

【问题讨论】:

    标签: java amazon-dynamodb dynamodb-queries


    【解决方案1】:

    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(强调我的):

    [...] 当用户执行需要它们的操作时,分页结果按需加载某些操作,例如 size(),必须获取整个列表,但结果是尽可能一页一页地延迟获取

    所以,如果您基本上不想处理分页,请使用query 方法。但请记住,如果您想返回所有结果(或知道它们的大小),您的应用程序最终仍需要对结果进行分页

    另一方面,QueryResultPage 更接近 DynamoDB API。您正在处理一个页面,您可以使用getLastEvaluatedKey() 获取要用于下一个setExclusiveStartKey 的参数(在您的DynamoDBQueryExpression 上)

    总结:

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

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

    查询表或二级索引并返回单页匹配结果。与查询方法一样,您必须指定分区键值和应用于排序键属性的查询过滤器。 但是,queryPage 只返回数据的第一“页”,即适合 1 MB 的数据量

    【讨论】:

    • 非常感谢您的回复。也感谢您抽出时间来回答这个问题。关于stream(),如果我这样做stream().map(do something with the data).collect(Collectors.toList());。它会加载所有数据吗?
    • 正如我在答案中所写 - 如果您对流的所有项目执行流操作,则所有页面都应该为您透明地加载。这意味着,如果您不希望加载其他页面stream().map(...).collect(...) 不会限制项目,则需要明确将流限制为初始页面
    • 好的,我明白了。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2022-08-24
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2011-12-12
    相关资源
    最近更新 更多