elasticsearch 深度分页查询 Search_after(图文教程)

这篇具有很好参考价值的文章主要介绍了elasticsearch 深度分页查询 Search_after(图文教程)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言
这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。
作者:神的孩子都在歌唱

一. 简介

search_after 是 Elasticsearch 提供的一种分页查询方式,它可以用来在已经排序的结果集中进行分页查询。

search_after查询步骤如下(下面有具体的例子帮助理解):

elasticsearch search_after,elasticsearch,elasticsearch,jenkins,大数据

最后一条排序结果相当于它的游标

优点:

  1. 性能优势: 相对于传统的 fromsize 参数来说,search_after 在处理大量数据时性能更好,因为它不需要跳过之前的结果集,不严格受制于 max_result_window,可以无限制往后翻页。 fromsize只能翻页10000条.
  2. 适用于实时数据: 在实时数据更新频繁的场景下,search_after 可以确保查询结果的准确性,因为它不会受到新数据插入的影响。
  3. 避免深度分页问题: 使用 search_after 可以避免深度分页问题,即当页数很大时,传统的分页方式性能会下降。

缺点:

  1. 需要结果排序: 使用 search_after 前需要对结果集进行排序,如果排序字段较多或者数据量较大,可能会影响性能。
  2. 只适用于唯一排序字段: search_after 只支持基于唯一排序字段的分页查询,如果有多个排序字段,需要确保排序字段的唯一性。
  3. 不支持随机访问: 由于 search_after 是基于上一页的最后一个文档进行分页,所以不支持随机访问,只能逐页查询。

使用场景:

  1. 大数据量分页查询: 当需要处理大量数据并进行分页查询时,search_after 可以提供更好的性能。
  2. 实时数据展示: 在实时数据展示的场景下,可以使用 search_after 来确保查询结果的准确性。
  3. 避免深度分页问题: 当需要避免深度分页问题时,可以考虑使用 search_after 来提高查询效率。

官方文档说明不再建议使用scroll滚动分页和from size分页,建议使用search_after

We no longer recommend using the scroll API for deep pagination. If you need to preserve the index state while paging through more than 10,000 hits, use the search_after parameter with a point in time (PIT).

我们不再建议使用滚动 API 进行深度分页。如果需要在分页超过 10,000 个命中时保留索引状态,请使用带有时间点 (PIT) 的 search_after 参数。

By default, you cannot use from and size to page through more than 10,000 hits. This limit is a safeguard set by the index.max_result_window index setting. If you need to page through more than 10,000 hits, use the search_after parameter instead.

默认情况下,您不能使用fromsize翻阅超过 10,000 个点击。该限制是由索引设置设置的保障措施 index.max_result_window。如果您需要翻阅超过 10,000 个点击,请使用search_after 参数代替。

二. 不带PIT的search_after查询

建议带PIT,我举的这个列子是帮助理解PIT的作用

2.1 构造数据

PUT /test/_bulk?refresh
{"index":{}}
{"name": "小狗", "leg": 4, "iswing": false}
{"index":{}}
{"name": "小鸡", "leg": 2, "iswing": true}
{"index":{}}
{"name": "小猫", "leg": 4, "iswing": false}

2.2 search_after分页查询

注意:当我们使用search_after时,from值必须设置为0或者-1。

首先我们通过排序查询10条数据

GET /test/_search
{
  "size": 10, 
  "sort": [
    {
      "name.keyword": {
        "order": "desc" // 对返回的值进行排序
      }
    }
  ]
}

elasticsearch search_after,elasticsearch,elasticsearch,jenkins,大数据

要获取下一页结果,需要使用最后一条文档的排序值(也就是sort列表里面的值) 作为 search_after 参数重新运行上一个搜索。

GET test/_search
{
  "size": 10, 
  "search_after": ["小鸡"],
  "sort": [
    {
      "name.keyword": {
        "order": "desc"
      }
    }
  ]
}

这样子他就会从排序好的name为小猫开始查询

elasticsearch search_after,elasticsearch,elasticsearch,jenkins,大数据

2.2 问题

  1. 每次检索新的结果页时更新数组,重复此过程。如果这些请求之间发生刷新,结果的顺序可能会发生变化,从而导致页面之间的结果不一致。为了防止这种情况,您可以创建一个时间点 (PIT) 来在搜索中保留当前索引状态。

  2. 排序的值不唯一,翻页的时候文档对应不上。为了防止这种情况,PIT 搜索请求都会添加一个名为 _shard_doc 的隐式排序字段,该字段也可以显式提供,这个字段在es中叫做 tiebreaker 。此字段包含每个文档的唯一值。如果您不包含tiebreaker字段,则分页结果可能会丢失或重复命中。

比如我在插入一只小鸟

PUT /test/_bulk?refresh
{"index":{}}
{"name": "小鸟", "leg": 2, "iswing": true}

在执行查询语句

GET test/_search
{
  "size": 10, 
  "search_after": ["小鸡"],
  "sort": [
    {
      "name.keyword": {
        "order": "desc"
      }
    }
  ]
}

可以看到查询的结果发生了变化,并且第11条应该还是小鸡而不是小鸟

elasticsearch search_after,elasticsearch,elasticsearch,jenkins,大数据

为了解决这种情况,es在7.x引入了PIT的概念,它相当于是 存储索引数据状态的轻量级视图。

三. 带PIT的search_after查询

一些关于PIT的知识:

PIT的快照时间点: 创建 PIT 时记录的是索引状态的快照,而不是实时数据。即使 PIT 不过期,它也只反映创建 PIT 时的索引状态,而不包括之后新增的数据。

数据更新延迟: 即使使用 PIT 进行查询,由于数据写入和索引过程中可能存在一定的延迟,新数据可能不会立即反映在查询结果中。这种延迟可能导致查询结果不是实时的。

实时性需求: 如果需要实时性较高的查询结果,可能需要结合其他机制或策略来确保数据的实时性,如定时刷新 PIT、定时重新创建 PIT 等。

PIT对于翻页的作用:PIT确保了在后续翻页的过程中,可能会有新数据写入等操作,但这些操作不会对原有结果集构成影响,保障数据的一致性。

关于 pit的官方文档

3.1 构建第一次查询条件

POST /test/_pit?keep_alive=1m

keep_alive必须要加上,它表示这个pit能存在多久,这里设置的是1分钟

elasticsearch search_after,elasticsearch,elasticsearch,jenkins,大数据

构建第一次查询条件

GET /_search
{
  "size": 10,
  "pit": {
    "id": "z9_qAwELdGVzdC0wMDAwMDQWVGxjUUVIUzhRQktTTkJRU3VQQXlodwAWWGlMYTRUQ2VUaE9PVlJHNzRTdHBVdwAAAAAAAAauuRZ3bEkwVkx1MlR6YVlsMUZ4MHpUV05nAAEWVGxjUUVIUzhRQktTTkJRU3VQQXlodwAA",
    "keep_alive":"1m"
  },
   "sort": [
    {
      "name.keyword": {
        "order": "desc"
      }
    }
  ]
}

输出值如下

elasticsearch search_after,elasticsearch,elasticsearch,jenkins,大数据

我上面展示的是最后一条文档,可以看到排序sort中莫名多了个28 ,这在es官方文档中叫做tiebreaker ,官方文档中解释如下

如果您使用 PIT,tiebreaker 是 隐含的排序值,是基于_shard_doc 的升序排序方式。 _shard_doc 值是 PIT 中的分片索引和 Lucene 的内部文档 ID 的组合,它对于每个文档都是唯一的 。您还可以在搜索请求中手动添加 tiebreaker 以自定义顺序:

网上解释:tiebreaker (决胜字段),tiebreaker 等价于_shard_doc。tiebreaker 本质是每个文档的唯一值,确保分页不会丢失或者分页结果数据出现重复(相同页重复或跨页重复)。

可以在sort里面加上_shard_doc 进行自定义排序

"sort": [
{
  "name.keyword": {
    "order": "desc"
  },
  "_shard_doc": "asc"
}

3.2 进行下一页查询

我们在拿它sort里面的值放入到search_after中进行下一页查询

在每个搜索请求中添加 keep_alive 参数来延长 PIT 的保留期,相当于是重置了一下时间

GET /_search
{
  "size": 10,
  "pit": {
    "id": "z9_qAwELdGVzdC0wMDAwMDQWVGxjUUVIUzhRQktTTkJRU3VQQXlodwAWWGlMYTRUQ2VUaE9PVlJHNzRTdHBVdwAAAAAAAAauuRZ3bEkwVkx1MlR6YVlsMUZ4MHpUV05nAAEWVGxjUUVIUzhRQktTTkJRU3VQQXlodwAA",
    "keep_alive":"1m"
  },
   "sort": [
    {
      "name.keyword": {
        "order": "desc"
      }
    }
  ],
  "search_after": [
      "小鸡",
      28
  ],
  "track_total_hits": false     // 禁用总点击率跟踪以加快分页速度     
}

通过以下输出可以看到。我们已经成功进入到下一页了

elasticsearch search_after,elasticsearch,elasticsearch,jenkins,大数据

这样子就能够成功进行分页查询了

3.3 删除PIT

完成后,您应该删除您的 PIT。

DELETE /_pit
{
    "id" : "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA=="
}

四.参考文章

https://blog.csdn.net/qq_26857259/article/details/134372438

https://blog.csdn.net/yangbindxj/article/details/123979413 有上一页方案

作者:神的孩子都在歌唱
本人博客:https://blog.csdn.net/weixin_46654114
转载说明:务必注明来源,附带本人博客连接。文章来源地址https://www.toymoban.com/news/detail-847595.html

到了这里,关于elasticsearch 深度分页查询 Search_after(图文教程)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Elasticsearch From/Size、Scroll、Search After对比

    Elasticsearch From/Size、Scroll、Search After对比 可以使用from和size参数对结果进行分页。from参数定义要获取的第一个结果的偏移量。 size 参数允许您配置要返回的最大匹配数。 简单来说,需要查询from + size 的条数时,coordinate node就向该index的其余的shards 发送同样的请求,等汇总到(

    2023年04月08日
    浏览(33)
  • ElasticSearch - DSL查询文档语法,以及深度分页问题、解决方案

    目录 一、DSL 查询文档语法 前言 1.1、DSL Query 基本语法 1.2、全文检索查询 1.2.1、match 查询 1.2.2、multi_match 1.3、精确查询 1.3.1、term 查询 1.3.2、range 查询 1.4、地理查询 1.4.1、geo_bounding_box 1.4.2、geo_distance 1.5、复合查询 1.5.1、相关性算分 1.5.2、function_score 1.5.3、boolean query 1.6、搜索

    2024年02月07日
    浏览(40)
  • es--Elastic Search深度分页问题分析及四种解决方案

    ​ Elasticsearch的深度分页是指当你需要查询的结果数量非常多时,需要分页查询的第n页时,每次查询都需要扫描前n-1页的数据来获取结果。这样会导致性能问题,因为它需要很长的时间来完成查询。 Scroll API: Scroll API可以让你在每个查询阶段中存储状态。这样,你就不需要从

    2024年02月08日
    浏览(32)
  • Elasticsearch Search API之(Request Body Search 查询主体)

    sentence 句子,使用Java的BreakIterator确定的下一个句子边界处的突出显示片段。您可以使用boundary_scanner_locale指定要使用的区域设置。unified highlighter高亮器默认行为。 word 单词,由Java的BreakIterator确定的下一个单词边界处高亮显示的片段。 boundary_scanner_locale 区域设置。该参数采

    2024年04月09日
    浏览(35)
  • Elasticsearch Search API之(Request Body Search 查询主体)(1)

    “failed”:0 }, “hits”:{ “total”:1, “max_score”:0.2876821, “hits”:[ { “_index”:“map_highlighting_01”, “_type”:“_doc”, “_id”:“erYsbmcBeEynCj5VqVTI”, “_score”:0.2876821, “_source”:{ “context”:“城中西路可以受理外地二代身份证的办理。” }, “highlight”:{ // @1 “context”:[ “城中西

    2024年04月13日
    浏览(40)
  • Elasticsearch Search Scroll API(滚动查询)

    参考:Elasticsearch Search Scroll API(滚动查询) - 简书 Elasticsearch 中,传统的分页查询使用 from+size 的模式, from 就是页码,从 0 开始。默认情况下,当 (from+1)*size 大于 10000 时,也就是已查询的总数据量大于 10000 时,会出现异常。 如下,用循环模拟一个连续分页查询: 最终当

    2023年04月20日
    浏览(35)
  • Elasticsearch ES 简单查询 Query String Search 入门

    尝试了text类型排序需要特别处理下. \\\"reason\\\" : \\\"Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [name] in order to load field data by uninverting the inverted index.

    2024年02月16日
    浏览(37)
  • ElasticSearch分页查询

    一、ES支持的三种分页查询方式 From + Size 查询 Scroll 遍历查询 Search After 查询 二、分布式系统中的深度分页问题 为什么分布式存储系统中对深度分页支持都不怎么友好呢? 首先我们看一下分布式存储系统中分页查询的过程。 假设在一个有 4 个主分片的索引中搜索,每页返回

    2024年02月08日
    浏览(34)
  • Java Elasticsearch分页查询

    核心代码 分页查询示例

    2024年02月13日
    浏览(30)
  • ElasticSearch分页查询缓慢问题记录

    前段时间因为 数据量越来越大 ,导致数据库的查询压力越来越大。所以决定将数据 刷入到ES中 进行查询,以 提高查询速度 。想法是好的,测试环境也没有仔细测。心想ES查询总不会慢了。再慢能慢到哪里去。放心大胆的上了生产环境,结果给我好好的上了一课。 因为有全

    2024年02月05日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包