

# 在 DynamoDB 中对表查询结果分页
<a name="Query.Pagination"></a>

DynamoDB *分页*来自 `Query` 操作的结果。利用分页，`Query` 结果将分成若干“页”大小为 1 MB（或更小）的数据。应用程序可以先处理第一页结果，然后处理第二页结果，依此类推。

单次 `Query` 只会返回符合 1 MB 大小限制的结果集。要确定是否存在更多结果，并一次检索一页结果，应用程序应执行以下操作：

1. 检查低级别 `Query` 结果：
   + 如果结果包含 `LastEvaluatedKey` 元素并且非空，请继续步骤 2。
   + 如果结果中*没有* `LastEvaluatedKey`，则表示没有其他要检索的项目。

1. 使用相同的 `KeyConditionExpression` 构造 `Query`。但是，此次获取来自步骤 1 的 `LastEvaluatedKey` 值，并将其用作新 `ExclusiveStartKey` 请求中的 `Query` 参数。

1. 运行新的 `Query` 请求。

1. 前往步骤 1。

换言之，`LastEvaluatedKey` 响应中的 `Query` 应该用作下一 `ExclusiveStartKey` 请求的 `Query`。如果 `LastEvaluatedKey` 响应中没有 `Query` 元素，则表示您已检索最后一页结果。如果 `LastEvaluatedKey` 不为空，并不一定意味着结果集中有更多数据。检查 `LastEvaluatedKey` 是否为空是确定您是否已到达结果集末尾的唯一方式。

您可以使用 AWS CLI 查看此行为。AWS CLI 向 DynamoDB 反复发送低级别 `Query` 请求，直到请求中不再有 `LastEvaluatedKey`。考虑以下 AWS CLI 示例，此示例检索特定年份的电影标题。

```
aws dynamodb query --table-name Movies \
    --projection-expression "title" \
    --key-condition-expression "#y = :yyyy" \
    --expression-attribute-names '{"#y":"year"}' \
    --expression-attribute-values '{":yyyy":{"N":"1993"}}' \
    --page-size 5 \
    --debug
```

通常，AWS CLI 自动处理分页。但是，在此例中，AWS CLI `--page-size` 参数限制了每页项目数。`--debug` 参数输出有关请求和响应的低级别信息。

如果您运行该示例，DynamoDB 的首次响应类似如下内容。

```
2017-07-07 11:13:15,603 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":5,"Items":[{"title":{"S":"A Bronx Tale"}},
{"title":{"S":"A Perfect World"}},{"title":{"S":"Addams Family Values"}},
{"title":{"S":"Alive"}},{"title":{"S":"Benny & Joon"}}],
"LastEvaluatedKey":{"year":{"N":"1993"},"title":{"S":"Benny & Joon"}},
"ScannedCount":5}'
```

响应中的 `LastEvaluatedKey` 指示并未检索所有项目。随后，AWS CLI 会将另一个 `Query` 请求发送到 DynamoDB。此请求和响应模式继续，直到收到最终响应。

```
2017-07-07 11:13:16,291 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":1,"Items":[{"title":{"S":"What\'s Eating Gilbert Grape"}}],"ScannedCount":1}'
```

如果不存在 `LastEvaluatedKey`，则表示没有其他要检索的项目。

**注意**  
AWS SDK 处理低级别的 DynamoDB 响应（包括是否存在 `LastEvaluatedKey`），并提供各种抽象概念对 `Query` 结果进行分页。例如，适用于 Java 的 SDK 文档接口提供 `java.util.Iterator` 支持，以便您能够一次处理一个结果。  
对于各种编程语言的代码示例，请参阅本地化的 [Amazon DynamoDB 入门指南](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/)和 AWS SDK 文档。

此外，您还可以通过使用 `Query` 操作的 `Limit` 参数来限制结果集中的项目数，以此减少页面大小。

有关用 DynamoDB 查询的更多信息，请参阅[在 DynamoDB 中查询表](Query.md)。