golang ES From size 分页查询 和 Scroll 分页查询 demo

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: golang ES From size 分页查询 和 Scroll 分页查询 demo

From Size 方式分页查询 demo

func TestESQueryDemo(client *elastic.Client) {
        // ES SDK 教程:https://www.yisu.com/zixun/694102.html
  query := elastic.NewBoolQuery().
                Must(elastic.NewMatchQuery("lastname", "smith")).
    Filter(elastic.NewTermQuery("age", "20")).
    Filter(elastic.NewRangeQuery("modify_time").Format("yyyy-MM-dd").Gte("2021-07-22").Lt("2021-07-23"))
  ctx := context.Background()
  index := "info"
  result, err := client.Search(index).Query(query).Size(20).From(0).Do(ctx)
  if err != nil {
        logs.Error("err=%v", err)
  }
  for page, hit := range result.Hits.Hits {
    //var t Employee
    //err := json.Unmarshal(*hit.Source, &t) //另一种取出的方法
    //if err != nil {
    //  fmt.Println("failed")
    //}
    //fmt.Printf("employee name %s:%s\n", t.FirstName, t.LastName)
    logs.Info("page=%v, hit=%v", page, hit)
  }
  logs.Info("result=%v, err=%v", *result.Hits, err)
}

其他 api 使用参考:go语言操作es的方法

Scroll 分页查询 demo

Form Size 方式最多查一万条记录(是总共 1w,不是单次 1w,就算每次只查 1 条,查 10000 次之后也会报错),即 from + size <= 10000,当索引第 10001 条数据时,会报错,比如当我设置 from=10000,size=1,查询时提示 Type: illegal_argument_exception, Reason: Result window is too large, from + size must be less than or equal to: [10000] but was [10001]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting.

当所请求的数据总量大于1w时,可用scroll来代替from+size。

scroll 查询 可以用来对 Elasticsearch 有效地执行大批量的文档查询。游标查询会取某个时间点的快照数据。 查询初始化之后索引上的任何变化会被它忽略。 它通过保存旧的数据文件来实现这个特性,结果就像保留初始化时的索引视图一样。

func TestESQueryDemo(client *elastic.Client) {
   defer logs.Flush()
   query := elastic.NewBoolQuery().
        Must(elastic.NewMatchQuery("lastname", "smith")).
        Filter(elastic.NewTermQuery("age", "20")).
        Filter(elastic.NewRangeQuery("modify_time").Format("yyyy-MM-dd").Gte("2021-07-22").Lt("2021-07-23"))
   ctx := context.Background()
   index := "info"
   result, err := client.Scroll(index).
      Query(query).
      Scroll("8s"). // 这个时间只需要能查到第一次时间片就够了,不是查询所有文档的时间
      Size(200).
      Do(ctx)
   scrollID := result.ScrollId
   logs.Info("total = %d, result=%v, err=%v", result.TotalHits(), *result.Hits, err)
   for {
      result, err = client.Scroll("2s").ScrollId(scrollID).Do(ctx) // 每次查询都会使用这个时间续期
      logs.Info("total = %d, result=%v, err=%v", result.TotalHits(), *result.Hits, err)
      if len(result.Hits.Hits) <= 0 {
         break
      }
      logs.Info("scrollID = %v", result.ScrollId)
      time.Sleep(1 * time.Second)
   }
   // 清除游标
   _, err = client.ClearScroll().ScrollId(result.ScrollId).Do(ctx)
}

关于 Scroll 查询返回 返回 EOF 错误

使用 Scroll 来分页查询,如果首次查询时发现无有效记录,即首次查询结果为空时,那么会返回 EOF 错误,而不是空的结果列表。此时,需要我们做一个判断,究竟是 EOF 错误则认为是返回结果为空,否则认为是发生了错误

if err == io.EOF {
  fmt.Println("the error equal io.EOF")
}
if err.Error() == "EOF" {
  fmt.Println("the error.Error() equal io.EOF")
}
fmt.Println(err) // 查询错误,而非数据为空

关于 Scroll 时间参数的说明

启用游标查询可以通过在查询的时候设置参数 scroll 的值为我们期望的游标查询的过期时间。

游标查询的过期时间会在每次做查询的时候刷新,所以这个时间只需要足够处理当前批的结果就可以了,而不是处理查询结果的所有文档的所需时间。

这个过期时间的参数很重要,因为保持这个游标查询窗口需要消耗资源,所以我们期望如果不再需要维护这种资源就该早点儿释放掉。

设置这个超时能够让 Elasticsearch 在稍后空闲的时候自动释放这部分资源。

参考:es scroll 时间_游标查询 Scroll | Elasticsearch: 权威指南 | ElasticElasticsearch的滚动查询---Scroll,解决ES每次最多查一万笔数据的问题

两种分页查询方式的对比

ES对于from+size的个数是有限制的,二者之和不能超过1w。当所请求的数据总量大于1w时,可用scroll来代替from+size。

ES的搜索是分2个阶段进行的,即Query阶段和Fetch阶段。 Query阶段比较轻量级,通过查询倒排索引,获取满足查询结果的文档ID列表。 而Fetch阶段比较重,需要将每个shard的结果取回,在协调结点进行全局排序。 通过From+size这种方式分批获取数据的时候,随着from加大,需要全局排序并丢弃的结果数量随之上升,性能越来越差。

而Scroll查询,先做轻量级的Query阶段以后,免去了繁重的全局排序过程。 它只是将查询结果集,也就是doc id列表保留在一个上下文里, 之后每次分批取回的时候,只需根据设置的size,在每个shard内部按照一定顺序(默认doc_id续), 取回这个size数量的文档即可。

由此也可以看出scroll不适合支持那种实时的和用户交互的前端分页工作,其主要用途用于从ES集群分批拉取大量结果集的情况,一般都是offline的应用场景。 比如需要将非常大的结果集拉取出来,存放到其他系统处理,或者需要做大索引的reindex等等。 不要把 scroll 用于实时请求,它主要用于大数据量的场景。例如:将一个索引的内容索引到另一个不同配置的新索引中。

参考:es scroll 时间_ElasticSearch教程之---Scroll查询mongo 返回EOF错误

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
11月前
|
JSON Linux Go
Golang之我想写个"web框架"-7: 完成一个“留言小demo”
Golang之我想写个"web框架"-7: 完成一个“留言小demo”
138 0
Golang:go-querystring将struct编码为URL查询参数的库
Golang:go-querystring将struct编码为URL查询参数的库
178 0
golang 协程并发代码 demo
golang 协程并发代码 demo
|
Java Linux Go
知识分享之Golang——Bleve中查询时指定具体字段Field和权重
知识分享之Golang篇是我在日常使用Golang时学习到的各种各样的知识的记录,将其整理出来以文章的形式分享给大家,来进行共同学习。欢迎大家进行持续关注。 知识分享系列目前包含Java、Golang、Linux、Docker等等。
109 0
知识分享之Golang——Bleve中查询时指定具体字段Field和权重
|
Go 前端开发
golang(3):beego CRUD demo (1)
本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/46699343 转载请一定注明出处! 1,beego 自带crud生成工具 工具执行非常简单: bee generate scaffold post -fields="title:string,body:text" 设置模块post,里面的file
1535 0
|
1天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
50 0
|
1天前
|
分布式计算 Java Go
Golang深入浅出之-Go语言中的分布式计算框架Apache Beam
【5月更文挑战第6天】Apache Beam是一个统一的编程模型,适用于批处理和流处理,主要支持Java和Python,但也提供实验性的Go SDK。Go SDK的基本概念包括`PTransform`、`PCollection`和`Pipeline`。在使用中,需注意类型转换、窗口和触发器配置、资源管理和错误处理。尽管Go SDK文档有限,生态系统尚不成熟,且性能可能不高,但它仍为分布式计算提供了可移植的解决方案。通过理解和掌握Beam模型,开发者能编写高效的数据处理程序。
140 1
|
1天前
|
缓存 测试技术 持续交付
Golang深入浅出之-Go语言中的持续集成与持续部署(CI/CD)
【5月更文挑战第5天】本文介绍了Go语言项目中的CI/CD实践,包括持续集成与持续部署的基础知识,常见问题及解决策略。测试覆盖不足、版本不一致和构建时间过长是主要问题,可通过全面测试、统一依赖管理和利用缓存优化。文中还提供了使用GitHub Actions进行自动化测试和部署的示例,强调了持续优化CI/CD流程以适应项目需求的重要性。
54 1
|
1天前
|
Kubernetes Cloud Native Go
Golang深入浅出之-Go语言中的云原生开发:Kubernetes与Docker
【5月更文挑战第5天】本文探讨了Go语言在云原生开发中的应用,特别是在Kubernetes和Docker中的使用。Docker利用Go语言的性能和跨平台能力编写Dockerfile和构建镜像。Kubernetes,主要由Go语言编写,提供了方便的客户端库与集群交互。文章列举了Dockerfile编写、Kubernetes资源定义和服务发现的常见问题及解决方案,并给出了Go语言构建Docker镜像和与Kubernetes交互的代码示例。通过掌握这些技巧,开发者能更高效地进行云原生应用开发。
54 1