5.4 分页 (Pagination)


文档摘要

5.4 分页 (Pagination) Elasticsearch 分页 (Pagination) 在 Elasticsearch 中,分页是指将搜索结果分成多个页面显示,以便用户可以逐步浏览大量数据。 Elasticsearch 提供了多种分页方法,可以根据不同的需求选择合适的方式。 和 这是最基本也是最常用的分页方式。 : 指定从哪个文档开始返回结果(偏移量)。 : 指定每个页面返回的文档数量。 代码示例: 详解: 上述查询会返回 索引中的前 10 个文档。 要获取第二页,可以将 设置为 10, 保持不变: 优点: 简单易用,适用于大多数场景。 缺点: 当 值很大时,性能会下降。 Elasticsearch 需要跳过大量的文档才能找到起始位置,这会消耗大量的 CPU 和内存资源。

5.4 分页 (Pagination)

Elasticsearch 分页 (Pagination)

在 Elasticsearch 中,分页是指将搜索结果分成多个页面显示,以便用户可以逐步浏览大量数据。 Elasticsearch 提供了多种分页方法,可以根据不同的需求选择合适的方式。

1. fromsize

这是最基本也是最常用的分页方式。

  • from: 指定从哪个文档开始返回结果(偏移量)。

  • size: 指定每个页面返回的文档数量。

代码示例:

GET /your_index/_search { "from": 0, // 从第一个文档开始(相当于第一页) "size": 10, // 每页返回 10 个文档 "query": { "match_all": {} } }

详解:

  • 上述查询会返回 your_index 索引中的前 10 个文档。

  • 要获取第二页,可以将 from 设置为 10,size 保持不变:

GET /your_index/_search { "from": 10, // 从第 11 个文档开始(相当于第二页) "size": 10, // 每页返回 10 个文档 "query": { "match_all": {} } }

优点:

  • 简单易用,适用于大多数场景。

缺点:

  • from 值很大时,性能会下降。 Elasticsearch 需要跳过大量的文档才能找到起始位置,这会消耗大量的 CPU 和内存资源。 例如,要获取第 1000 页(每页 10 个文档),from 将是 9990。 Elasticsearch 需要检索并跳过前 9990 个文档,这会变得非常低效。

  • 不适用于深度分页(例如,超过 10000 个文档)。 Elasticsearch 默认限制了 from + size 的最大值,以防止内存溢出。

2. search_after

search_after 是一种更高效的分页方式,尤其是在需要深度分页时。 它使用前一页最后一个文档的排序值作为起始点,而不是像 from 那样使用偏移量。

代码示例:

GET /your_index/_search { "size": 10, "query": { "match_all": {} }, "sort": [ { "_id": "asc" } // 必须指定排序字段,且需要保证排序字段的唯一性 ] }

上述查询返回第一页数据,假设最后一篇文档的 _idAWaJkGOK0qumFvj-H9vL,则获取第二页数据的查询如下:

GET /your_index/_search { "size": 10, "query": { "match_all": {} }, "sort": [ { "_id": "asc" } ], "search_after": [ "AWaJkGOK0qumFvj-H9vL" // 上一页最后一个文档的排序值 ] }

详解:

  • sort: 必须指定排序字段,且需要保证排序字段的唯一性。 通常使用 _id 或其他具有唯一性的字段。

  • search_after: 是一个数组,包含上一页最后一个文档的排序值。 数组中值的顺序必须与 sort 中字段的顺序一致。

  • 第一次查询时,不需要 search_after 参数。

  • 每次查询后,需要从结果中提取最后一个文档的排序值,并在下一次查询中使用。

优点:

  • 性能优于 fromsize,尤其是在深度分页时。 search_after 不需要跳过大量的文档,而是直接从指定的排序值开始检索。

  • 适用于实时滚动浏览数据。

缺点:

  • 需要指定排序字段,且排序字段需要保证唯一性。

  • 不适用于随机访问页面,只能按顺序浏览。

  • 如果数据在分页期间发生变化,可能会导致结果不一致。

注意事项:

  • 为了保证每次分页的唯一性,通常会组合多个排序字段,确保即使第一个排序字段的值相同,也能通过后续字段进行区分。

3. Scroll API

Scroll API 适用于需要一次性获取大量数据,且不需要实时性的场景,例如数据导出、数据备份等。 它会创建一个快照,并在快照上进行迭代,因此即使数据在滚动期间发生变化,也不会影响结果。

代码示例:

POST /your_index/_search?scroll=1m // 1m 表示 scroll 上下文保持 1 分钟 { "size": 1000, "query": { "match_all": {} } }

上述查询会返回一个 scroll_id,用于后续的滚动请求。

POST /_search/scroll { "scroll": "1m", "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBZXF0ZHRvX3F1ZXJ5DnF1ZXJ5VGhlbkZldGNoAwAAAAAAABkUFkZlT0F0V1J3UE1rV1h3c3JvT2J4dwAAAAAAAAAZFBZGZU9BdFdSd1BNa1dYd3Nyb09ieHcAAAAAAAAAGRQWRmVPT0F0V1J3UE1rV1h3c3JvT2J4dwAAAAAAAAAZFBZGZU9BdFdSd1BNa1dYd3Nyb09ieHcAAAAAAAAAGRQWRmVPT0F0V1J3UE1rV1h3c3JvT2J4dw==" }

详解:

  • scroll: 指定 scroll 上下文的保持时间。 例如,1m 表示保持 1 分钟。 应该足够长,以便完成所有滚动请求。

  • scroll_id: 第一次查询返回的 scroll_id,用于后续的滚动请求。

  • 每次滚动请求都会返回一个新的 scroll_id,应该在下一次请求中使用。

  • 当没有更多数据时,滚动请求将返回一个空的 hits 数组。

  • 完成滚动后,应该清除 scroll 上下文,释放资源:

DELETE /_search/scroll { "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBZXF0ZHRvX3F1ZXJ5DnF1ZXJ5VGhlbkZldGNoAwAAAAAAABkUFkZlT0F0V1J3UE1rV1h3c3JvT2J4dwAAAAAAAAAZFBZGZU9BdFdSd1BNa1dYd3Nyb09ieHcAAAAAAAAAGRQWRmVPT0F0V1J3UE1rV1h3c3JvT2J4dwAAAAAAAAAZFBZGZU9BdFdSd1BNa1dYd3Nyb09ieHcAAAAAAAAAGRQWRmVPT0F0V1J3UE1rV1h3c3JvT2J4dw==" }

优点:

  • 适用于一次性获取大量数据,且不需要实时性的场景。

  • 性能优于 fromsize,尤其是在需要获取所有数据时。

  • 可以保证数据的一致性,即使数据在滚动期间发生变化。

缺点:

  • 不适用于实时滚动浏览数据。

  • 需要手动管理 scroll 上下文。

  • 会占用服务器资源,应该及时清除 scroll 上下文。

分页方式对比

特性 fromsize search_after Scroll API
适用场景 常规分页 深度分页 数据导出/备份
性能 较低 (深度分页) 较高 较高
实时性 较高 较高 较低
数据一致性 较低 (数据变化) 较低 (数据变化) 较高
易用性 简单 较复杂 较复杂
是否随机访问

分页流程图

总结

Elasticsearch 提供了多种分页方式,可以根据不同的需求选择合适的方式。

  • fromsize 适用于常规分页,简单易用,但性能较低,不适用于深度分页。

  • search_after 适用于深度分页,性能较高,但需要指定排序字段,且不适用于随机访问页面。

  • Scroll API 适用于一次性获取大量数据,且不需要实时性的场景,性能较高,可以保证数据的一致性,但需要手动管理 scroll 上下文。

在实际应用中,应该根据具体的业务场景和数据量选择合适的分页方式,并进行性能测试,以确保分页功能的效率和稳定性。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U