分页搜索—Elastic Stack 实战手册

简介: 在查询场景中,从 Elasticsearch 中取得结果,根据不同场景,有多种不同的方式。

970X90.png

· 更多精彩内容,请下载阅读全本《Elastic Stack实战手册》

· 加入创作人行列,一起交流碰撞,参与技术圈年度盛事吧

创作人:张超

在查询场景中,从 Elasticsearch 中取得结果,根据不同场景,有多种不同的方式。

  • 通过 from 、size 进行分页
  • 通过 scroll 拉取大量数据
  • 通过 search_after 拉取大量数据

每种方式有其各自的使用场景,或者说他们是为了解决某种场景而设计的。

from + size

搜索引擎的场景,类似 google 搜索,翻页操作一般是人为触发的,并且人的行为一般不会翻页太多,from+size 这种最经典的翻页模式是为了解决用户对于 TopN 的需求,用户希望找到 TopN 个最匹配的文档。其使用方式类似 SQL 中的 LIMIT关键字,Elasticserach 使用 from 和 size 两个参数来控制翻页:

  • size: 要返回的结果数量,默认为 10
  • from: 要跳过的结果数量,默认为 0

如果每页显示 5 条结果,下面的命令可以得到 1-3 页的结果:

GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10

分页搜索实现方式是:

  1. 每个分片各自查询的时候先构建 from+size 的优先队列,然后将所有的文档 ID 和排序值返回给协调节点。
  2. 协调节点创建 size 为 number_of_shards * (from + size) 的优先队列,对数据节点的返回结果进行合并,取全局的 from+size 返回给客户端

这种工作模式的主要代价在于,协调节点需要等待所有分片返回结果,然后再全局排序。因此会创建非常大的优先队列,需要控制分页的深度,Elasticsearch 默认最多返回 10000 个文档。但是有些时候,用户需要遍历取回所有文档,甚至可以不关心排序。在数据库中取回全部结果可以使用游标查询的方式,类似的概念在 Elasticsearch 中叫做 scroll。

scroll

scroll 可以用于拉取全量数据,他的工作模式不需要像 from + size 一样全局排序,因此没有深分页的代价,例如 reindex 本质上就是 scroll+bulk。使用 scroll 可以简单的在查询语句中添加 scroll 参数:

POST /my-index-000001/_search?scroll=1m

上面的查询语句会返回一个 ID,后面可以根据这个 ID 顺序拉取结果:

POST /my-index-000001/_search/scroll                                                               
{
  "scroll" : "1m",                                                                 
  "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" 
} 

Elasticsearch 将查询后的上下文保存在服务端,因此客户端可以依据这个 scroll_id 依次获取后续的数据。

这个上下文也必然有一个生命周期,因为他会一直占用服务端资源。在这个例子中,我们设置 scroll 窗口保存 1 分钟的时间。1 分钟之内,你都可以使用 scroll_id 来拉取数据。当然,你也可以在拉取完成之后根据 scroll_id 手工清理上下文。

search_after

如果说 scroll 是把上下文保存在服务端,而 search_after 要求数据中存在一个无重复,可以用于排序的字段,需要客户端每次传入上次查到的最后结果,然后获取其随后的数据。

由于随后的请求每次都是查询出来的,如果数据发生变化,就可能出现跨页面结果不一致的情况,为了防止这种情况,需要在请求中加一个参数来设置当前的索引状态保留时间。

POST /my-index-000001/_pit?keep_alive=1m

PIT 是 point in time 的简写,他是一个轻量级的视图。上述请求返回一个 ID:

{
  "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA=="
}

随后的请求中你需要带上他。可以通过下面的方式,获取第一页的结果,其中的特别之处在于,要指定进行排序的字段:

GET /_search
{
  "size": 10000,
  "query": {
    "match" : {
      "user.id" : "elkbee"
    }
  },
  "pit": {
        "id":  "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==", 
        "keep_alive": "1m"
  },
  "sort": [ 
    {"@timestamp": "asc"}
  ]
}

在返回结果中,会携带 sort 字段的值,

{
  "hits" : {
    "hits" : [
      {
        "sort" : [
          4294967298                              
        ]
      }
    ]
  }
}

你需要在下次请求的时候带上他:

GET /_search
{
  "size": 10000,
  "query": ...
  "pit": {
        "id":  ...
        "keep_alive": ...
  },
  "sort": [
    {"@timestamp": "asc"}
  ],
  "search_after": [                                
    4294967298
  ]                    
}

类似 scroll,pit 请求返回的 ID 也可以手工清理。

最后我们总结一下每种分页方式的特点:

  • from+size 支持跳页,不适合深分页;
  • scroll 不支持跳页,适合拉取大量数据,不适合大量并发
  • search_after 不支持跳页,适合拉取大量数据

Scroll 和 search_after 都可以用于深分页,search_after 需要提供一个主键字段进行排序,默认为 _shard_doc,它是 shard index 与 Lucene 内部 ID 的组合值。在服务端保存的上下文要比 scroll 小,目前官方推荐使用 search_after 代替 scroll。

相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。  
相关文章
|
数据处理 C# C++
如何使用C#和C++结构体实现Socket通信
如何使用C#和C++结构体实现Socket通信
868 0
SAP报错:科目要求一个成本分配的处理方式
SAP MM模块有时候会经常遇见这样的报错:科目XXXXX要求一个成本会计分配,很多小伙伴就无从下手!笔者也在一次做采购订单运费的条件类型测试时,在MIGO收货时,系统提示“科目XXXXX要求一 一个成本会计分配”报错!
SAP报错:科目要求一个成本分配的处理方式
|
8月前
|
人工智能 自然语言处理 前端开发
建造者还是饲料投喂者?AI Agent搭建师职业焦虑与“工具反噬”的幽灵
当AI Agent自主迭代,程序员正面临“工具反噬”的焦虑:我们是智能体的建筑师,还是数据饲养员?本文剖析职业危机根源,揭示从编码者到“人机指挥家”的进化之路,探寻人类在智能洪流中不可替代的价值锚点——意图、判断与创造力。
337 3
|
8月前
|
编解码 并行计算 物联网
【实战教程】Flux.1-dev 360° 全景驾驶舱:从零到一的“零坑”部署指南
本教程教你如何在24G显存单卡环境下部署超大文生图模型Flux.1-dev。通过ModelScope极速下载、Hugging Face身份鉴权与显存顺序卸载技术,解决下载慢、授权难、显存溢出等问题,实现稳定推理。
1201 1
|
SQL 缓存 分布式计算
vivo 湖仓架构的性能提升之旅
聚焦 vivo 大数据多维分析面临的挑战、StarRocks 落地方案及应用收益。 在 **即席分析** 场景,StarRocks 使用占比达 70%,查询速度提升 3 倍,P50 耗时从 63.77 秒缩短至 22.30 秒,查询成功率接近 98%。 在 **敏捷 BI** 领域,StarRocks 已完成 25% 切换,月均查询成功数超 25 万,P90 查询时长缩短至 5 秒,相比 Presto 提升 75%。 在 **研发工具平台** 方面,StarRocks 支持准实时数据查询,数据可见性缩短至 3 分钟,查询加速使 P95 延迟降至 400 毫秒,开发效率提升 30%。
vivo 湖仓架构的性能提升之旅
|
存储 Docker Python
docker 部署 sftp
本文介绍SFTP服务的部署与配置,包括users.conf用户配置规则、Docker容器运行命令及上传目录权限说明,重点解析atmoz/sftp镜像的chroot机制与子目录映射,确保用户登录后正确访问/upload目录,并提供Python脚本实现文件上传示例。
918 12
docker 部署 sftp
|
存储 监控 测试技术
Kibana 的 Alert—Elastic Stack 实战手册
Kibana 的 Alert 模块主要用于 Elastic Stack 的监控告警。以一种相对较低的使用成本,将复杂的查询条件,编辑完成后监控不同的 Elastic Stack 的技术产品中产生的数据,最终把符合条件的告警信息以需要的方式反馈给用户。
5950 0
Kibana 的 Alert—Elastic Stack 实战手册
|
弹性计算 运维 Kubernetes
阿里云轻量应用服务器与轻量容器服务简介与区别及收费标准参考
轻量应用服务器是深受个人和普通企业用户亲耐的一款轻量级云服务器产品,提供精品应用一键部署,支持一站式的域名、网站、安全、运维、应用管理等服务,极大优化搭建简单应用的体验,降低了入门级用户使用云计算产品的门槛。轻量容器服务是专为学生、个人开发者等用户打造的轻量级容器服务,帮助您在云上快速了解容器和Kubernetes(简称K8s)相关的基础概念和轻松进行入门实践。本文为大家介绍一下阿里云轻量应用服务器与轻量容器服务的区别以及收费标准,以供参考。
阿里云轻量应用服务器与轻量容器服务简介与区别及收费标准参考
|
SQL 安全 Java
MyBatis(6)#{}和${}的区别
在MyBatis中,`#{}`和`${}`是用于在SQL语句中嵌入参数的两种方式。`#{}`用于预处理参数,可以防止SQL注入;而`${}`进行直接字符串替换,适用于动态插入表名或列名,但存在SQL注入风险。建议优先使用`#{}`,并在必要时谨慎使用`${}`。
697 3
|
机器学习/深度学习 PyTorch TensorFlow

热门文章

最新文章