当前位置: 首页 > 后端技术 > Java

Elasticsearch全局、过滤器和基数聚合

时间:2023-04-01 13:38:41 Java

1。背景这里记录一下global、filters和cardinality的聚合操作。二、解释1、全局globalaggregation是全局聚合,不受查询条件的限制,对所有文档进行聚合。全局聚合器只能充当顶级聚合器,因为将全局聚合器嵌入另一个桶聚合器没有意义。比如:我们有50个文档,通过查询条件过滤后有10个文档。这时候我想统计一共有多少个文档。是50,因为全局统计不受查询条件的限制。2.过滤器定义了一个多桶聚合,其中每个桶都与一个过滤器相关联。每个桶收集与其关联的过滤器匹配的所有文档。比如:我们一共有50个文档,通过查询条件过滤后有10个文档。这时候我想统计一下这10个文档中出现了多少个带有info这个词的文档,有多少个带有warn这个词的文档。3、cardinality类似于SQL中的COUNT(DISTINCT(field)),但这是近似统计,基于HyperLogLog++实现。3.需求我们有一组日志,每条日志有两个字段:id和message。此时根据message字段,过滤掉带有infowarn的日志,然后统计:系统中总共有多少条日志(global+cardinality),info和warn级别的日志有多少条(filters)4.Preconditions4.1创建mappingPUT/index_api_log{"settings":{"number_of_shards":1},"mappings":{"properties":{"message":{"type":"text"},"id":{"type":"long"}}}}4.2准备数据PUT/index_api_log/_bulk{"index":{"_id":1}}{"message":"thisisinfomessage-01","id":1}{"index":{"_id":2}}{"message":"这是信息message-02","id":2}{"index":{"_id":3}}{"message":"thisiswarnmessage-01","id":3}{"index":{"_id":4}}{"message":"thisiserrormessage","id":4}{"index":{"_id":5}}{"message":"thisisinfoandwarnmessage","id":5}5、现实3的需求5.1dslPOST/index_api_log/_search{"size":0,"query":{"bool":{"must":[{“匹配”:{“消息”:“信息警告”}}]}},“聚合”:{“agg_01”:{“过滤器”:{“过滤器”:{“信息”:{“匹配”:{“消息”:“信息”}},“警告”:{“匹配”:{“消息”:“警告”}}},“other_bucket”:真,“other_bucket_key”:“其他”}},“agg_02”:{“全球”:{},“聚合”:{“总计”:{“基数":{"field":"id","precision_threshold":30000}}}}}}5.2java代码@Test@DisplayName("globalandfiltersandcardinalityaggregation")publicvoidtest01()throwsIOException{SearchRequestrequest=SearchRequest.of(searchRequest->searchRequest.index("index_api_log")//查询带有信息的日志并在message.query(query->query.bool(bool->bool.must(must->must.match(match->match.field("message").query("infowarn")))))//查询结果不返回.size(0)//首先aggregation.aggregations("agg_01",agg->agg.filters(过滤器->filters.filters(f->f.array(Arrays.asList(//在上一步查询的结果中,聚合包含信息的消息Query.of(q->q.match(m->m.field("message").query("info"))),//在上一步的查询结果中,聚合包含warn的消息Query.of(q->q.match(m->m.field("message").query("warn"))))))//如果上一步查询中有non-info和warn,是否聚合到另一个bucket中。otherBucket(true)//给另一个桶一个名字.otherBucketKey("other")))//二次聚合.aggregations("agg_02",agg->agg//这里的全局聚合只能放在最上面global(global->global)//子聚合,数据来自所有文档,不受上一步查询结果的限制。cardinality(cardinality->//统计字段cardinality.field("id")//精度,默认值30000,最大值也是40000,不超过这个值的聚合的近似准确值.precisionThreshold(30000))));System.out.println("请求:"+request);SearchResponseresponse=client.search(request,String.class);System.out.println("response:"+response);}5.3运行结果6.实现代码https://gitee.com/huan1993/spring-cloud-parent/blob/master/es/es8-api/src/main/java/com/huan/es8/aggregations/bucket/GlobalAndFiltersAggs.java7,参考文档1,https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-global-聚合.html