前言

今天我们讲ES的高亮和聚合查询,聚合功能是ES很重要的功能,它基于查询条件来对数据进行分桶和计算。它提供了类似于关系型数据库的SUM,COUNT, AVG , Group By 等功能。聚合也可以嵌套,可以组成复杂的操作。

聚合概述

ES聚合包括:Metrics Aggregations 指标聚合 ;Bucket Aggregations 桶聚合 ;Pipeline Aggregations 管道聚合 ;Matrix Aggregations 矩阵聚合;

  • Metrics Aggregations 指标聚合 :提供了类似于关系型数据库的 count,sum,avg,min,max 等统计方式。
  • Bucket Aggregations 桶聚合 :桶聚合类似于分组统计 group by , 它执行的是对文档分组的操作,把特性相同的文档分到一个桶里(理解成一个group)。
  • Pipeline Aggregations 管道聚合 : 管道聚合主要是把其他聚合的结果再进行聚合
  • Matrix Aggregations 矩阵聚合:矩阵聚合,此功能处于技术预览阶段,可能会在未来版本中更改或删除。

下面是聚合语法如下

GET /index/type/_search
{"query":{...},"aggs":{"指定聚合名字":{"指定聚合方式":{"field":"按那个字段聚合"}}}
}

注意:本文并不会把ES所有的聚合都讲到,您可以通过官网自行学习其他的聚合如何使用 ,参考文档 ES聚合查询

指标聚合 Metrics Aggregations

指标聚合,它可以对文档数据进行权重统计,比如求:最大值,最小值,求和,求平均等。就如何关系型数据库中的统计函数。

MAX;MIN;SUM;AVG

  • Max Aggregation,求最大值。如同于关系型数据库中的 max函数

  • Min Aggregation,求最小值。如同于关系型数据库中的 min 函数

  • Sum Aggregation,求和。如同于关系型数据库中的 sum 函数

  • Avg Aggregation,求平均数。如同于关系型数据库中的 avg函数

案例:[Max Aggregation] : 查询价格最大值

GET /orders/_doc/_search
{"query":{"match":{"title":"鼠标"}},"aggs":{                    //代表是聚合查询"maxAmount":{            //取个名字,任意指定"max":{                 //使用max聚合方式"field":"amount"     //按照amount字段做max聚合}}}
}

效果如下

多种聚合一起用

统计聚合: Stats Aggregation

Stats Aggregation,统计聚合可以统计出某个字段的 :min、max、sum、count、avg5个值,案例:求金额的:最小,最大,总和,数量,平均值。

GET /orders/_doc/_search
{"query":{"match":{"title":"鼠标"}},"aggs":{"statsAmount":{"stats":{"field":"amount"}}}
}

执行效果如下

值计数聚合 Value Count Aggregation

Value Count Aggregation,值计数聚合,可以按照某一个字段进行数量统计,类似于关系型数据库的count(id)的效果,案例:统计订单数量

GET /orders/_doc/_search
{"query":{"match":{"title":"鼠标"}},"aggs":{"countAmount":{"value_count":{"field":"id"}}}
}

执行效果如下

去重 distinct 聚合

distinct 聚合可以根据某个字段计算文档非重复的个数(去重计数),相当于sql中的distinct。案例:计算出商品数量,标题去重

GET /orders/_doc/_search
{"aggs":{"countAmount":{"cardinality":{"field":"status"}}}
}

查询效果如下

百分比统计Percentiles Aggregation

Percentiles Aggregation,百分比聚合,可以统计出满足某个值的文档在所有文档中的占比,默认返回[ 1, 5, 25, 50, 75, 95, 99 ]分位上的值。案例:
- “1.0”:100.0 :代表金额<=100的文档在所有文档中占比:10%

百分比排名 Percentile Ranks Aggregation

百分比排名 Percentile Ranks Aggregation ,可以统计出满足某个值的文档在所有文档中的占比,案例:统计金额为200 和 400 的占比

GET /orders/_doc/_search
{"aggs":{"ranksAmount":{"percentile_ranks":{"field":"amount","values":["200","400"]}}}
}

查询效果如

最高匹配 Tops Hits

Top Hits Aggregation,最高匹配权值聚合。获取到每组前n条数据,相当于sql 中Top(group by 后取出前n条): 案例:统计最前面2条

GET /orders/_doc/_search
{"aggs":{"countAmount":{"top_hits":{"size":"2"}}}
}

查询效果如下

Top Hits 一般作为子聚合使用,以此来聚合每个桶中的最高匹配的文档,较为常用的统计

桶聚合

桶聚合类似于分组统计 group by , 它执行的是对文档分组的操作,把特性相同的文档分到一个桶里(理解成一个group)。

词聚合 Terms Aggregation

Terms Aggregation,词聚合。基于某个字段进行分组统计文档个数。默认返回顺序是按照文档个数多少排序。类似于关系型数据库的 group by 。

案例:按照状态统计每种状态是文档个数

GET /orders/_doc/_search
{"aggs":{"statusAggr":{"terms":{"field":"status"}}}
}

执行效果:

status 为 1的文档数为:3 ,status为0的文档数为 1 ; size是取前面10条。

子聚合使用,统计每种status下的文档数量,以及总金额

GET /orders/doc/_search
{"aggs":{"statusAggr":{"terms":{"field":"status","size":10},"aggs": { //子聚合,把上面聚合的结果作为数据源继续做sum聚合"amountAgg": {"sum": {"field":"amount"}}}}}
}

执行效果

过滤聚合 Filter Aggregation

过滤聚合,对文档进行过滤,案例:先过滤title包含“鼠标”的,然后再使用status进行terms统计

GET /orders/doc/_search
{"aggs":{"filterAggr":{"filter": {//过滤"match":{"title":"鼠标"}},"aggs": {"statusAgg":{"terms": {"field": "status","size": 10}}}}}
}

执行效果

范围聚合 Range Aggregation

Range Aggregation 范围聚合,根据某个字段的范围值来分桶聚合。可以通过from和to来指定范围。案例:统计金额范围在 50到500之间的文档数量。

直方图 Histogram Aggregation

Histogram Aggregation 直方图聚合,根据某个数值型字段进行动态计算分桶,案例:根据金额进行分桶,分桶的的间距为200,如下:
解释:200到400的有3个文档 ; 600到800的有3个文档

聚合实战

该案例在上一 篇案例(DSL查询+高亮) 的基础上加上聚合查询,这里简单演示了3种聚合:sum ; stats ;terms 代码如下:

@Testpublic void testSearch(){//查询构建器NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();//设置分页:0开始第一页, 每页10数builder.withPageable(PageRequest.of(0,10));//设置排序 : 金额倒排builder.withSort(SortBuilders.fieldSort("amount").order(SortOrder.DESC));//构建组合查询BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//标题包含鼠标boolQuery.must(QueryBuilders.matchQuery("title","鼠标"))//状态值查询//.filter(QueryBuilders.termQuery("status",1))//金额范围查询.filter(QueryBuilders.rangeQuery("amount").gte(10).lte(2000));//添加查询条件builder.withQuery(boolQuery);//设置高亮=========================================================================================================HighlightBuilder.Field  highlightField = new HighlightBuilder.Field("title").preTags("<span style='color:red'>").postTags("</span>");builder.withHighlightFields(highlightField);//聚合查询=============================================================================================================//对amount使用sum聚合SumAggregationBuilder sumAggregationBuilder = AggregationBuilders.sum("amountSumAgg").field("amount");//stats聚合,包括:sum,avg,min,max,countStatsAggregationBuilder statsAggregationBuilder = AggregationBuilders.stats("amountStatsAgg").field("amount");//对status使用terms桶聚合TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("statusTermsAgg").field("status");//把聚合添加到builderbuilder.addAggregation(sumAggregationBuilder).addAggregation(statsAggregationBuilder).addAggregation(termsAggregationBuilder);//执行搜索=============================================================================================================//Page<OrderDoc> page = orderRepository.search(builder.build());AggregatedPage<OrderDoc> page = template.queryForPage(builder.build(), OrderDoc.class, highlightResultMapper);//获取条数System.out.println("总元素个数:"+page.getTotalElements());//打印列表page.getContent().forEach(System.out::println);//聚合结果=============================================================================================================Map<String, Aggregation> aggregationMap = page.getAggregations().getAsMap();aggregationMap.entrySet().forEach(aggregationEntry -> {//聚合名字String aggName = aggregationEntry.getKey();Aggregation aggregation = aggregationEntry.getValue();System.out.println("聚合名字 = "+aggName);if(aggregation instanceof ParsedLongTerms){//对应terms聚合ParsedLongTerms agg = (ParsedLongTerms) aggregation;agg.getBuckets().forEach(bucket->{String key = bucket.getKeyAsString();long docCount = bucket.getDocCount();System.out.println("key = "+key +" ; docCount = "+docCount);});}if(aggregation instanceof ParsedStats){//对应stats聚合ParsedStats agg = (ParsedStats) aggregation;System.out.println(agg.getAvg());System.out.println(agg.getMax());System.out.println(agg.getCount());System.out.println(agg.getSum());System.out.println(agg.getMin());}if(aggregation instanceof ParsedSum){//对应sum聚合ParsedSum agg = (ParsedSum) aggregation;System.out.println(agg.getValue());}});}

你可以编写一个结果对象对文档列表数据和聚合数据进行封装,然后返回给前端页面。这里打印的效果如下

文章结束,希望对你有所帮助,喜欢的话请给个好评,评论过百,我就是秃头也出下章。

七.全文检索ElasticSearch经典入门-聚合查询相关推荐

  1. java操作es聚合操作并显示其他字段_java使用elasticsearch分组进行聚合查询过程解析...

    这篇文章主要介绍了java使用elasticsearch分组进行聚合查询过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java连接elas ...

  2. java操作es聚合操作并显示其他字段_java使用elasticsearch分组进行聚合查询(group by)-项目中实际应用...

    java连接elasticsearch 进行聚合查询进行相应操作 一:对单个字段进行分组求和 1.表结构图片: 根据任务id分组,分别统计出每个任务id下有多少个文字标题 1.SQL:select i ...

  3. 【ElasticSearch教程】--- Elasticsearch文档聚合查询(十四)

    聚合查询 对查询的结果进行统计,分组等操作的时候就需要用的聚合操作, 聚合操作需要用到聚合操作对应的参数.参数字段名叫:aggs. 分组统计(terms) {"aggs": { / ...

  4. ElasticSearch java API - 聚合查询-聚合多字段聚合demo

    以球员信息为例,player索引的player type包含5个字段,姓名,年龄,薪水,球队,场上位置. index的mapping为: "mappings": {"pl ...

  5. es java聚合查询只有10_关于在elasticSearch中使用聚合查询后只显示10个bucket的问题...

    先看下面es查询语句 { "size": 0, "aggs" : { "all_articleId" : { "terms&quo ...

  6. php聚合查询,php elasticsearch 聚合查询(Aggregation)

    Elasticsearch中的聚合查询,类似SQL的SUM/AVG/COUNT/GROUP BY分组查询,主要用于统计分析场景. 这里主要介绍PHP Elasticsearch 聚合查询的写法,如果不 ...

  7. Elasticsearch 入门(1):基本概念,安装教程,索引的创建,查询,删除,主键查询,修改,添加,聚合查询,条件查询

    Elasticsearch 入门 基本概念 The Elastic Stack, 包括 Elasticsearch.Kibana.Beats 和 Logstash(也称为 ELK Stack).能够安 ...

  8. Elasticsearch笔记(七):聚合查询

    聚合框架有助于根据搜索查询提供聚合数据.聚合查询是数据库中重要的功能特性,ES作为搜索引擎兼数据库,同样提供了强大的聚合分析能力.它基于查询条件来对数据进行分桶.计算的方法.有点类似于 SQL 中的 ...

  9. 全文检索-ElasticSearch入门

    文章目录 1. 基于Lucene的全文检索 1.1 全文检索概念 1.2 全文检索过程 1.3 全文检索相关概念 1.4 全文检索的使用场景 2. ElasticSearch 2.1 ElasticS ...

最新文章

  1. 【共享单车】—— React后台管理系统开发手记:权限设置和菜单调整(未完)...
  2. UNIX网络编程:I/O复用技术(select、poll、epoll)
  3. HTTP协议理解——计算机网络
  4. ejb 属于哪一层,作用是什么,什么时候用
  5. curl and wget
  6. 安卓数据库的使用方式
  7. Ubuntu下安装Oracle Instant Client
  8. java 性能问题排查与性能优化
  9. 分布式存储 HDFS原理
  10. 债券基金的涨跌受什么影响
  11. IDA Pro 4.9.0.863 Advanced Full with SDK
  12. 计算机网络每日一题,计算机一级考试每日练习(一)附答案
  13. 计算机学院元旦晚会对联,学校元旦对联加横批
  14. 海思3516开发记录-AAC音频解码
  15. mysql删去root用户无法登录_MySQL误删root用户导致无法登陆解决方法
  16. 全力加速,绝对实力!从Q3财报看华米科技的逆势而为
  17. 0x010D99A9 处有未经处理的异常(在 XXX.exe 中): 0xC00000FD: Stack overflow (参数: 0x00000000, 0x06772000)
  18. 关于LaTeX中的正文的字体大小
  19. 基于Python制作的24点游戏生成器
  20. 探测输入字符串是否为UTF8编码

热门文章

  1. ★Oracle imp/impdp 导入dmp文件到数据库
  2. 浅谈Web App前端设计原则
  3. python文本字符分析
  4. 图像重采样/插值原理与其在MRI脑影像分辨率修改中的应用——将尺寸为1mm标准模板修改成体素尺寸为3、6、8mm标准模板(FSL、SPM12、NIfTI_20140122、dpabi、nilearn)
  5. 博客导航——一站式搜索(所有博客的汇总帖)【微信开发】
  6. 如何修改excel的修改日期?
  7. u大侠pe系统桌面计算机,如何使用U大侠PE系统修复引导文件
  8. Linux环境C语言开发基础
  9. latex数字引用参考文献
  10. oracle数据的安装,与基本配置