go语言使用olivere/elastic es客户端实现SearchAfter深度分页

我们go项目里使用的es客户端是olivere/elastic包,资料比较少,SearchAfter的实现更是少,所以记录下来给有缘人,也给记性差的自己。

关于深度分页、浅分页的区别优缺点另行了解,我的es版本是6.4,过低版本会不支持

关于SearchAfter官方的简单实例

https://www.elastic.co/guide/en/elasticsearch/reference/6.4/search-request-search-after.html

简单演示下客户端的创建:

import "github.com/olivere/elastic"
// 获取客户端对象,这里可以包装单例使用
esClient, err = elastic.NewClient(
   elastic.SetURL(你的es库host,多参数),
   elastic.SetSniff(false),
   elastic.SetHealthcheckInterval(10 * time.Second),
   elastic.SetGzip(true),
)

 查询方法

其中Query方法的参数需要各位组装自己的查询条件,参考官方实例

忽略了数据的处理和,重点在深度分页的用法

// 深度分页查询方法,根据上一次查询的最后一条数据(该条数据的中用于排序的字段值,支持多字段)查询size条数据
// 入参为上次调用的返回值,即上次查询最后一条数据中用于排序的字段值
// 深度分页不能指定from(只能是0/-1),必须有size和sort
func searchByAfter(searchAfter string) string {
    searchService := esClient.Search(要查询的index/列表).
    Query(你的dsl查询对象).
    // 要排序的字段,false为desc即逆序
    Sort("sn", false).
    // 每页的个数
    Size(10).
    // 为了兼容第一次请求,判断searchAfter是否为空
    if searchAfter != "" {
            searchService.SearchAfter(searchAfter)
   }
   // 执行查询
   res, err := searchService.Do(esCtx)
   // 省略判断err和res中数据的处理逻辑,比如转化成对象列表作为返回值
   list := doSomething(res)
   if len(list) <= 0 {
       return ""
   }
   // 本例根据Sn字段排序,所以返回最后一条数据的Sn
   return list, list[len(list)-1].Sn
}

查询方法的使用

是我的单测简化出来的,肯定不能直接运行,用于演示循环分页查询

// 对深度分页方法的使用测试
func TestEsOrdersDao_OrdersByConditions(t *testing.T) {
   var searchAfter string
   for {
       sn := searchByAfter(searchAfter)
       result = append(result, list...)
       // 即本次查询为空,没有下一条了
       if sn == "" {
         break
      }
      searchAfter = sn
   }
   // 因为没有返回数据,完成后没什么好输出的,可以返回查询到的数据列表append到数组中汇总
   // 断点调试可以看到每次循环查询到的数据和每次返回的searchAfter
}

 

你可能感兴趣的:(GO)