Elasticsearch 分页

17 Mar 2025 | 5 分钟阅读

在开始使用 Elasticsearch 中的分页并了解如何操作之前,重要的是要知道什么是分页。 因此,让我们首先从分页开始。

每次我们在网上搜索内容时,它都会返回大量结果。 这些结果可能成百上千,有时甚至数百万,分布在多个页面上。 每个页面都有多个记录。 这种机制被称为分页。 分页有助于用户高效地查找必要的信息。

通常,每个页面包含 10 条记录,但这并不是限制。 您可以设置每页要显示的记录数。 下图显示了分页的外观,以便您更好地理解它。

Elasticsearch Pagination

分页是具有相似内容的页面序列。 它也称为分页,可以帮助用户直接转到任何页面。 因此,他们不需要在页面上向下滚动太久。 它可以节省用户宝贵的时间。 大多数时候,分页位于页面底部。 但是,我们也可以将其放置在任何我们想要的位置,例如页面顶部。 请注意,我们可以将分页与滚动结合使用。

Elasticsearch 中的分页

Elasticsearch 允许用户执行分页。 这很容易也很简单。 在 Elasticsearch 中,有两个属性 fromsize,它们可以非常有效地执行分页。 这些参数如下

From - 此属性用于指定每页的起始点,以开始在索引中搜索记录。 意思是它指定 Elasticsearch 应从索引中的哪个记录开始搜索。 在此,您可以定义要从头开始跳过的项目数。

Size - 此属性用于指定每页要搜索的记录数。 这意味着在此属性中设置将返回多少结果。

因此,借助分页,我们能够提取特定数量的记录以返回给用户。

如何在 Elasticsearch 中执行分页

在 Elasticsearch 中,我们可以借助 fromsize 属性来执行分页,如上所述。 这将帮助您从索引中获取特定数量的结果并将它们返回给用户。 但是,这些 from 和 size 参数仅适用于 10k 个搜索结果。

让我们看一个查询示例,以在 Elasticsearch 中进行分页 -

这里reasoning是索引的名称,而_search是 Elasticsearch API。 根据此查询,它将从 reasoning 索引返回 15 条记录。

显而易见的是,每种技术都有一些缺点和优点。 Elasticsearch 分页也有一个小问题。 当对 Elasticsearch 索引执行搜索请求,并且我们获得超过 10000 个结果的列表时。 from + size 索引不能大于 index.max - result - window. 其默认值在创建索引时设置为 10000。

我们有解决方案,您可以选择使用 scroll APIsearch_after 参数来处理此问题。 如果您需要前进,请使用 search_after。 另一方面,如果您需要转储包含超过一万个文档的整个索引,请使用 scroll API。

我们将详细讨论这两种解决方案

如果列表超过 10000 项,如何解决?

如果您有一个超过 10k 项的列表,Elasticsearch 提供了解决方案,如下所示 -

1. Elasticsearch 的 Scroll API

Elasticsearch 为其用户提供 scroll API 来处理此类问题。 如果请求很大并且延迟不太重要,我们可以使用 scroll API。 这意味着如果没有时间问题并且请求也很大,则 scroll API 非常有用。

建议将 scroll API 用于深度滚动。 但是,由于此解决方案,网络上发出了很多警告。 尽管如此,我们还是实现了此解决方案。

预计它会非常慢,可能需要大约 10 分钟才能执行。 此外,它也是一种昂贵的解决方案,因为 Elasticsearch 在每次迭代之间都保持状态。 因此,它不是实时用户请求的最佳解决方案。 总之,它不适用于实时请求,并且 scroll 上下文也很昂贵。 请参见以下示例

示例

我们必须发送一个初始请求才能开始滚动。 通常,此请求会在服务器上启动搜索上下文。 在此查询请求中,您需要在 scroll 参数中指定 scroll 时间(即,scroll=TTL),这意味着它保持活动状态的时间。 此查询请求将使上下文保持活动 2 分钟。

2. 使用 search_after 参数

借助 fromsize 参数,我们可以经济高效地执行分页。 但是,当达到深度分页时,成本会上升太多。 Scroll API 适用于大型请求,但是没有响应的时间限制。 因此,它不适合实时用户请求。

Elasticsearch 提供了一个 search_after 参数,该参数适用于实时使用请求。 search_after 参数提供了一个实时游标。 它不用于跳转到随机页面,它有助于并行滚动多个查询。 请注意,搜索请求占用的堆内存和时间相当于 from + size。 请参见以下示例

3. 增加 index.max_result_window 的值

基本上,此值 (index.max_result_window) 有助于保护 Elasticsearch 集群内存免受大型查询的影响。 通过增加此值,集群延迟可能会崩溃。

Elasticsearch 不允许用户分页超出 index.max_result_window 设置。 这不是限制,而是防止深度分页的保护措施。 默认情况下,其值为 10000。因此,from + size 应小于此值。

4. 将列表限制为 10k 篇文章

如果需要在超过 10k 个结果上进行分页,则此请求可能不够精确。 因为分页超过 10k 个结果并不好。 Elasticsearch 不仅仅是一个搜索引擎。 有些文章必须出于 SEO 目的显示整个历史记录,这些历史记录超过 10k 篇文章。

已实施的解决方案

让我们借助一个流程图来理解,在其中我们在这里描述了两种解决方案 -

  • 像往常一样执行经典的 Elasticsearch 查询,如果 from + size 的值小于或等于 10000(max_result_window 的默认值)。
  • 否则,使用预先计算的页面并执行基于前一页的最后一篇文章的 search_after 查询。

请参见以下流程图

Elasticsearch Pagination

前 10k 个项目中的页面是新鲜的,因为它们是按需计算的。 而其他页面没有预期的那么新鲜。 这些页面是静态的并且是预先计算的,但对于 SEO 目的来说是可以接受的。 为此执行查询请求。


下一个主题Elasticsearch 快照