Elasticsearch Scroll 取出所有满足条件的数据
背景:es中每天3亿日志,需要通过日志生成一些报表出来,但是日志不能直接使用,需要对日志进行拆分重组,存储之后才能聚合。es查询结果默认最大是10000条,查询超过10000条的数据,无法通过分页查询查出来。
处理方法 :
1.调大max_result_window。
优点:只需要修改配置即可,代码不需要修改。
缺点:会大量消耗服务性能,影响查询效率,如果数据量剧增需要频繁调整该参数。
2.通过Scroll api 查询
话不多直接上代码
EsData struct {
Host string `json:"host"`
AccessTime string `json:"access_time"`
}
func ScrollEsData(esQuery EsQuery) (res []*EsData) {
res = make([]*EsData, 0)
boolQuery := esQuery.GetBoolQuery().Must(elastic.NewMatchAllQuery())
var scrollId string // 用于存储scroll ID的切片
scroll := es.client.Scroll("index_name").
Size(consts.EsMaxSize). // 每批取10000条
Query(boolQuery)
for {
searchResult, err := scroll.Do(s.Ctx)
if err == io.EOF {
break // 没有更多的结果,退出循环
}
if err != nil {
fmt.Println("scroll err:", err)
break
}
for _, hit := range searchResult.Hits.Hits {
tmp := new(EsData)
err = json.Unmarshal(hit.Source, tmp)
if err != nil {
fmt.Println("unmarshal err:%s", err)
return
}
res = append(res, tmp)
}
scrollId = searchResult.ScrollId
}
_, err := es.client.ClearScroll().ScrollId(scrollId).Do(s.Ctx)
if err != nil {
log.Println("Failed to clear scroll ID %v: %v", scrollId, err)
}
return ipData
}