精华内容
下载资源
问答
  • 前言 在使用mongo数据库时,简单的查询基本上可以满足大多数的业务场景...里面记录了每种水果的价格,现在我要统计一下,各种水果在这张表中出现的次数,如果不用聚合查询的话,思路应该是这样,先把表中所有的数据都取
  • 主要介绍了java使用elasticsearch分组进行聚合查询过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 简单的聚合查询构造( ) 简单聚合结果解析和“压缩”( ) 干净、简约的界面(在结合) 经过良好测试的代码库 可根据不同需求进行配置和定制 去做 确定公共函数的更好命名约定(以更好地反映底层分桶和度量聚合...
  • GROUP BY子句要和聚合函数配合使用才能完成分组查询,在SELECT查询的字段中,如果没有使用聚合函数就必须出现在ORDER BY子句中。分组查询后,查询结果为一个或多个列分组后的结果集。 GROUP BY语法 SELECT 列名, ...
  • C# List多条件查询聚合查询,List条件查询Where与GroupBy聚合查询
  • 聚合查询分页测试termsAgg.size(2147483647); //指定最大统计显示多少行步骤1:全量聚合,size设置为: 2147483647。 ES5.X/6.X版本设置为2147483647 ,它等于2^31-1,请看该地方代码
  • 主要介绍了Django ORM 聚合查询和分组查询实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 主要介绍了ThinkPHP5联合(关联)查询、多条件查询与聚合查询,结合实例形式总结分析了thinkPHP5常用查询操作技巧,需要的朋友可以参考下
  • ES 聚合查询结果转换成相应的对象集合,ES 聚合查询结果转换成相应的对象集合
  • mongotemplate按日期聚合查询,实现 $year,$month聚合功能
  • 结合实际项目,使用ElasticSearch restful接口实现对ES的增删改查以及聚合查询
  • 主要给大家介绍了关于mongodb中按天进行聚合查询的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mongodb具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • FastRAQ:大数据环境中范围聚合查询的快速方法
  • 前面一篇文章已经详细介绍了查询相关的API,但是当时并没有总结关于Aggregation聚合查询这一方面的内容,本篇文章单独对聚合查询做一个总结。 聚合查询提供了功能可以分组并统计你的数据。理解聚合最简单的方式就是...

    目录

    一、简介

    二、数据准备

    三、度量(metric)聚合

    三、bucketing(桶)聚合

    四、聚合查询嵌套使用

    五、总结


    一、简介

    前面一篇文章已经详细介绍了查询相关的API,但是当时并没有总结关于Aggregation聚合查询这一方面的内容,本篇文章单独对聚合查询做一个总结。

    聚合查询提供了功能可以分组并统计你的数据。理解聚合最简单的方式就是可以把它粗略的看做SQL的GROUP BY操作和SQL的聚合函数。

    ElasticSearch中常用的聚合有两种:

    • metric(度量)聚合:度量类型聚合主要针对的number类型的数据,需要ES做比较多的计算工作,类似于关系型数据库的组函数操作;
    • bucketing(桶)聚合:划分不同的“桶”,将数据分配到不同的“桶”里。非常类似sql中的group语句的含义,类似于关系型数据库的分组操作;

    关于聚合查询的官方文档地址(es7.6版本):https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations.html#search-aggregations

    ES中的聚合API如下:

    "aggregations" : {  // 表示聚合操作,可以使用aggs替代
        "<aggregation_name>" : {  // 聚合名,可以是任意的字符串。用做响应的key,便于快速取得正确的响应数据。
            "<aggregation_type>" : {   // 聚合类别,就是各种类型的聚合,如min等
                <aggregation_body>  // 聚合体,不同的聚合有不同的body
            }
            [,"meta" : {  [<meta_data_body>] } ]?   
            [,"aggregations" : { [<sub_aggregation>]+ } ]?   // 嵌套的子聚合,可以有0或多个
        }
        [,"<aggregation_name_2>" : { ... } ]*  // 另外的聚合,可以有0或多个
    }

    二、数据准备

    为了后面演示聚合查询,我们首先需要准备一些数据,批量插入测试数据:

    # 批量插入测试数据
    POST /user/info/_bulk
    {"index":{"_id":1}}
    {"name":"zs","realname":"张三","age":10,"birthday":"2018-12-27","salary":1000.0,"address":"广州市天河区科韵路50号"}
    {"index":{"_id":2}}
    {"name":"ls","realname":"李四","age":20,"birthday":"2017-10-20","salary":2000.0,"address":"广州市天河区珠江新城"}
    {"index":{"_id":3}}
    {"name":"ww","realname":"王五","age":30,"birthday":"2016-03-15","salary":3000.0,"address":"广州市天河区广州塔"}
    {"index":{"_id":4}}
    {"name":"zl","realname":"赵六","age":40,"birthday":"2003-04-19","salary":4000.0,"address":"广州市海珠区"}
    {"index":{"_id":5}}
    {"name":"tq","realname":"田七","age":50,"birthday":"2001-08-11","salary":5000.0,"address":"广州市天河区网易大厦"}
    

    插入完成后,查看索引数据:

    可见,数据成功插入,下面我们分别对度量聚合、桶聚合进行详细的介绍。 

    三、度量(metric)聚合

    • Avg Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-metrics-avg-aggregation.html

    平均值聚合查询,用于计算从聚合的文档中提取的数值的平均值,这些值可以从文档中的特定数值字段中提取,也可以由提供的脚本生成。

    假设数据由代表用户工资的文件组成,我们可以将他们的平均工资为:

    POST /user/info/_search?size=0
    {
      "aggs": {
        "avg_salary": {
          "avg": {
            "field": "salary"
          }
        }
      }
    }

    上述聚合计算所有文档的平均级别。聚合类型为avg,字段设置定义计算平均值的文档的数字字段。以上将返回以下内容:

    .............
      "aggregations" : {
        "avg_salary" : {
          "value" : 3000.0
        }
      }
    
    

    可以看到,平均工资查询出来为3000元。

    聚合的名称(上面的avg_salary)还充当键,通过它可以从返回的响应中检索聚合结果。

    • Max Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-metrics-max-aggregation.html

    最大值查询,跟踪并返回从聚合文档中提取的数值的最大值。这些值可以从文档中的特定数值字段中提取,也可以由提供的脚本生成。

    如:查询员工的最高工资

    POST /user/info/_search?size=0
    {
      "aggs": {
        "max_salary": {
          "max": {
            "field": "salary"
          }
        }
      }
    }

    以上将返回以下内容:

    ..........
      "aggregations" : {
        "max_salary" : {
          "value" : 5000.0
        }
      }
    

     可以看到,成功查询出最高工资为5000元。

    • Min Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-metrics-min-aggregation.html

    最小值查询,跟踪并返回从聚合文档中提取的数值中的最小值。

    如:查询员工最低工资

    POST /user/info/_search?size=0
    {
      "aggs": {
        "min_salary": {
          "min": {
            "field": "salary"
          }
        }
      }
    }

    以上查询返回如下结果:

    ........
      "aggregations" : {
        "min_salary" : {
          "value" : 1000.0
        }
      }
    

    可以看到,成功查询到最低工资1000元。 

    • Sum Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-metrics-sum-aggregation.html

    求和聚合查询,对从聚合的文档中提取的数值进行汇总。

    如,统计所有员工的总工资

    POST /user/info/_search?size=0
    {
      "aggs": {
        "sum_salary": {
          "sum": {
            "field": "salary"
          }
        }
      }
    }

    以上查询返回如下结果:

    ......
      "aggregations" : {
        "sum_salary" : {
          "value" : 15000.0
        }
      }
    

    可以看到,成功查询总工资为15000元。

    • Stats Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-metrics-stats-aggregation.html

    统计查询,一次性统计出某个字段上的常用统计值。返回的统计信息包括:最小值,最大值,总和,计数和平均。

    POST /user/info/_search?size=0
    {
      "aggs": {
        "price_stats": {
          "stats": {
            "field": "salary"
          }
        }
      }
    }

    以上查询返回如下结果:

    ......
      "aggregations" : {
        "price_stats" : {
          "count" : 5,
          "min" : 1000.0,
          "max" : 5000.0,
          "avg" : 3000.0,
          "sum" : 15000.0
        }
      }
    

    可以看到,stats聚合查询同时返回了我们前面介绍了一些max、min、sum、avg等信息。

    • Value Count Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-metrics-valuecount-aggregation.html

    统计某字段有值的文档数。

    POST /user/info/_search?size=0
    {
      "aggs": {
        "price_value_count": {
          "value_count": {
            "field": "salary"
          }
        }
      }
    }

    如上查询下面结果:

    ......
      "aggregations" : {
        "price_value_count" : {
          "value" : 5
        }
      }
    
    

    还有一些其他的聚合查询,如:

    Cardinality Aggregation :值去重计数

    Extended Stats Aggregation:高级统计,比stats多4个统计结果: 平方和、方差、标准差、平均值加/减两个标准差的区间。

    Geo Bounds Aggregation:求文档集中的地理位置坐标点的范围

    Geo Centroid Aggregation:求地理位置中心点坐标值

    Percentiles Aggregation:占比百分位对应的值统计

    Percentile Ranks Aggregation:统计值小于等于指定值的文档占比

    感兴趣的小伙伴可以跟着官网示例,自己手动去练练手,试一下。 

    三、bucketing(桶)聚合

    • Range Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-bucket-range-aggregation.html

    基于多桶值源的聚合,使用户能够定义一组范围——每个范围表示一个桶。在聚合过程中,将根据每个bucket范围和相关/匹配文档的“bucket”检查从每个文档提取的值。

    注意,此聚合包含每个范围的from值并排除to值。

    自定义区间范围的聚合,我们可以自己手动地划分区间,ES会根据划分出来的区间将数据分配不同的区间上去。

    如: 统计0-20岁,20-40岁,40~60岁各个区间段的用户人数

    POST /user/info/_search
    {
      "aggs": {
        "age_ranges_count": {
          "range": {
            "field": "age",
            "ranges": [
              {
                "from": 0,
                "to": 20
              },
              {
                "from": 20,
                "to": 40
              },
              {
                "from": 40,
                "to": 60
              }
            ]
          }
        }
      }
    }

    以上查询返回下面结果:

    ...........
      "aggregations" : {
        "age_ranges_count" : {
          "buckets" : [
            {
              "key" : "0.0-20.0",
              "from" : 0.0,
              "to" : 20.0,
              "doc_count" : 1
            },
            {
              "key" : "20.0-40.0",
              "from" : 20.0,
              "to" : 40.0,
              "doc_count" : 2
            },
            {
              "key" : "40.0-60.0",
              "from" : 40.0,
              "to" : 60.0,
              "doc_count" : 2
            }
          ]
        }
      }
    
    

    可以看到,成功统计出各个我们指定的区间段的用户人数。如果第一个区间开始值和最后一个区间结束值不想指定的话,可以不用写from和to,如下:

    GET /_search
    {
        "aggs" : {
            "price_ranges" : {
                "range" : {
                    "field" : "price",
                    "ranges" : [
                        { "to" : 100.0 },
                        { "from" : 100.0, "to" : 200.0 },
                        { "from" : 200.0 }
                    ]
                }
            }
        }
    }

    响应结果就类似下面:*-100.0、200.0-*,使用*代表某个区间值。

    {
        ...
        "aggregations": {
            "price_ranges" : {
                "buckets": [
                    {
                        "key": "*-100.0",
                        "to": 100.0,
                        "doc_count": 2
                    },
                    {
                        "key": "100.0-200.0",
                        "from": 100.0,
                        "to": 200.0,
                        "doc_count": 2
                    },
                    {
                        "key": "200.0-*",
                        "from": 200.0,
                        "doc_count": 3
                    }
                ]
            }
        }
    }
    • Terms Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-bucket-terms-aggregation.html

    自定义分组依据Term,对分组后的数据进行统计。

    如:根据年龄分组,统计相同年龄的用户

    POST /user/info/_search
    {
      "aggs": {
        "age_count": {
          "terms": {
            "field": "age",
            "size": 3
          }
        }
      }
    }

    响应结果如下:

    .....
    "aggregations" : {
        "age_count" : {
          "doc_count_error_upper_bound" : 0,
          "sum_other_doc_count" : 2,
          "buckets" : [
            {
              "key" : 10,
              "doc_count" : 1
            },
            {
              "key" : 20,
              "doc_count" : 1
            },
            {
              "key" : 30,
              "doc_count" : 1
            }
          ]
        }
      }
    • Date Range Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-bucket-daterange-aggregation.html

    专用于日期值的范围聚合,专门针对date类型的字段。此聚合与Range Aggregation常规范围聚合的主要区别在于,可以用日期数学表达式表示from和to值,而且还可以指定返回from和to响应字段的日期格式。注意,此聚合包含每个范围的from值并排除to值。

    • now+10y:表示从现在开始的第10年。
    • now+10M:表示从现在开始的第10个月。
    • 1990-01-10||+20y:表示从1990-01-01开始后的第20年,即2010-01-01。
    • now/y:表示在年位上做舍入运算。

    如: 统计生日在2017年、2018年、2019年的用户

    POST /user/info/_search
    {
      "aggs": {
        "birthday_count": {
          "date_range": {
            "field": "birthday",
            "format": "yyyy-MM-dd",
            "ranges": [
              {
                "from": "now/y-1y",
                "to": "now/y"
              },
              {
                "from": "now/y-2y",
                "to": "now/y-1y"
              },
              {
                "from": "now/y-3y",
                "to": "now/y-2y"
              }
            ]
          }
        }
      }
    }

    其中:

    • now/y:当前年的1月1日 
    • now:当前时间
    • now/y-1y:当前年上一年的1月1日

    响应结果:

    ......
    "aggregations" : {
        "birthday_count" : {
          "buckets" : [
            {
              "key" : "2017-01-01-2018-01-01",
              "from" : 1.4832288E12,
              "from_as_string" : "2017-01-01",
              "to" : 1.5147648E12,
              "to_as_string" : "2018-01-01",
              "doc_count" : 1
            },
            {
              "key" : "2018-01-01-2019-01-01",
              "from" : 1.5147648E12,
              "from_as_string" : "2018-01-01",
              "to" : 1.5463008E12,
              "to_as_string" : "2019-01-01",
              "doc_count" : 1
            },
            {
              "key" : "2019-01-01-2020-01-01",
              "from" : 1.5463008E12,
              "from_as_string" : "2019-01-01",
              "to" : 1.5778368E12,
              "to_as_string" : "2020-01-01",
              "doc_count" : 0
            }
          ]
        }
      }
    • Histogram Aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-bucket-histogram-aggregation.html

    直方图聚合,它将某个number类型字段等分成n份,统计落在每一个区间内的记录数。它与前面介绍的Range聚合非常像,只不过Range可以任意划分区间,而Histogram做等间距划分。既然是等间距划分,那么参数里面必然有距离参数,就是interval参数。

    如:根据年龄间隔(20岁)统计各个年龄段的员工总人数

    POST /user/info/_search
    {
      "aggs": {
        "age_histogram_count": {
          "histogram": {
            "field": "age",
            "interval": 20
          }
        }
      }
    }

    响应结果如下:

    ......
    "aggregations" : {
        "age_histogram_count" : {
          "buckets" : [
            {
              "key" : 0.0,
              "doc_count" : 1
            },
            {
              "key" : 20.0,
              "doc_count" : 2
            },
            {
              "key" : 40.0,
              "doc_count" : 2
            }
          ]
        }
      }
    • Date histogram aggregation

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations-bucket-datehistogram-aggregation.html

    日期直方图聚合,专门对时间类型的字段做直方图聚合。这种需求是比较常用见得的,我们在统计时,通常就会按照固定的时间断(1个月或1年等)来做统计。

    如:按年统计用户生日的总人数

    POST /user/info/_search
    {
      "aggs": {
        "birthday_data_histogram_count": {
          "date_histogram": {
            "field": "birthday",
            "interval": "year",
            "format": "yyyy-MM-dd"
          }
        }
      }
    }

    响应结果如下:

    ......
    "aggregations" : {
        "birthday_data_histogram_count" : {
          "buckets" : [
            {
              "key_as_string" : "2001-01-01",
              "key" : 978307200000,
              "doc_count" : 1
            },
            {
              "key_as_string" : "2002-01-01",
              "key" : 1009843200000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2003-01-01",
              "key" : 1041379200000,
              "doc_count" : 1
            },
            {
              "key_as_string" : "2004-01-01",
              "key" : 1072915200000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2005-01-01",
              "key" : 1104537600000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2006-01-01",
              "key" : 1136073600000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2007-01-01",
              "key" : 1167609600000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2008-01-01",
              "key" : 1199145600000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2009-01-01",
              "key" : 1230768000000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2010-01-01",
              "key" : 1262304000000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2011-01-01",
              "key" : 1293840000000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2012-01-01",
              "key" : 1325376000000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2013-01-01",
              "key" : 1356998400000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2014-01-01",
              "key" : 1388534400000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2015-01-01",
              "key" : 1420070400000,
              "doc_count" : 0
            },
            {
              "key_as_string" : "2016-01-01",
              "key" : 1451606400000,
              "doc_count" : 1
            },
            {
              "key_as_string" : "2017-01-01",
              "key" : 1483228800000,
              "doc_count" : 1
            },
            {
              "key_as_string" : "2018-01-01",
              "key" : 1514764800000,
              "doc_count" : 1
            }
          ]
        }
      }

    除了上述介绍的几种桶聚合查询,elasticsearch官网还提供了很多其他各种各样的聚合查询,有兴趣的小伙伴们可以前往官网进行学习。 

    四、聚合查询嵌套使用

    聚合操作是可以嵌套使用的。通过嵌套,可以使得metric类型的聚合操作作用在每一bucket上。我们可以使用ES的嵌套聚合操作来完成稍微复杂一点的统计功能。

    如:统计每年中用户的最高工资

    POST /user/info/_search
    {
      "aggs": {
        "birthday_data_histogram_count": {
          "date_histogram": {
            "field": "birthday",
            "interval": "year",
            "format": "yyyy-MM-dd"
          },
          "aggs": {
            "max_salary": {
              "max": {
                "field": "salary"
              }
            }
          }
        }
      }
    }

    响应结果:

    .....
    "aggregations" : {
        "birthday_data_histogram_count" : {
          "buckets" : [
            {
              "key_as_string" : "2001-01-01",
              "key" : 978307200000,
              "doc_count" : 1,
              "max_salary" : {
                "value" : 5000.0
              }
            },
            {
              "key_as_string" : "2002-01-01",
              "key" : 1009843200000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2003-01-01",
              "key" : 1041379200000,
              "doc_count" : 1,
              "max_salary" : {
                "value" : 4000.0
              }
            },
            {
              "key_as_string" : "2004-01-01",
              "key" : 1072915200000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2005-01-01",
              "key" : 1104537600000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2006-01-01",
              "key" : 1136073600000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2007-01-01",
              "key" : 1167609600000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2008-01-01",
              "key" : 1199145600000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2009-01-01",
              "key" : 1230768000000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2010-01-01",
              "key" : 1262304000000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2011-01-01",
              "key" : 1293840000000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2012-01-01",
              "key" : 1325376000000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2013-01-01",
              "key" : 1356998400000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2014-01-01",
              "key" : 1388534400000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2015-01-01",
              "key" : 1420070400000,
              "doc_count" : 0,
              "max_salary" : {
                "value" : null
              }
            },
            {
              "key_as_string" : "2016-01-01",
              "key" : 1451606400000,
              "doc_count" : 1,
              "max_salary" : {
                "value" : 3000.0
              }
            },
            {
              "key_as_string" : "2017-01-01",
              "key" : 1483228800000,
              "doc_count" : 1,
              "max_salary" : {
                "value" : 2000.0
              }
            },
            {
              "key_as_string" : "2018-01-01",
              "key" : 1514764800000,
              "doc_count" : 1,
              "max_salary" : {
                "value" : 1000.0
              }
            }
          ]
        }
      }

    可以看到,先通过date_histogram按照年分组,然后再通过嵌套max聚合查询统计出每年最高工资是多少。

     如:求每个年龄区间段的工资总和

    POST /user/info/_search
    {
      "aggs": {
        "age_ranges_count": {
          "range": {
            "field": "age",
            "ranges": [
              {
                "from": 0,
                "to": 20
              },
              {
                "from": 20,
                "to": 40
              },
              {
                "from": 40,
                "to": 60
              }
            ]
          },
          "aggs": {
            "sum_salary": {
              "sum": {
                "field": "salary"
              }
            }
          }
        }
      }
    }

    响应结果:

    ......
    "aggregations" : {
        "age_ranges_count" : {
          "buckets" : [
            {
              "key" : "0.0-20.0",
              "from" : 0.0,
              "to" : 20.0,
              "doc_count" : 1,
              "sum_salary" : {
                "value" : 1000.0
              }
            },
            {
              "key" : "20.0-40.0",
              "from" : 20.0,
              "to" : 40.0,
              "doc_count" : 2,
              "sum_salary" : {
                "value" : 5000.0
              }
            },
            {
              "key" : "40.0-60.0",
              "from" : 40.0,
              "to" : 60.0,
              "doc_count" : 2,
              "sum_salary" : {
                "value" : 9000.0
              }
            }
          ]
        }
      }

    五、总结

    本篇文章主要总结了elasticsearch提供的聚合查询,聚合查询类似于我们关系型数据库中的group by分组统计信息,这种需求很常见。文章通过详细的示例分别介绍了常见的几种度量聚合、桶聚合查询,在实际工作中,需要结合具体的业务查询需求灵活使用不同的聚合统计函数,更多详细使用方法可参见官网。希望对小伙伴们的学习有所帮助,由于笔者水平有限,文中可能存在有不对之处,还望指正,相互学习,一起进步!

    参考文档:

    https://www.elastic.co/guide/en/elasticsearch/reference/7.6/search-aggregations.html

    https://www.cnblogs.com/wangzhuxing/p/9581947.html#_label1_2

    展开全文
  • MongoDB之聚合查询

    千次阅读 2018-08-26 15:12:29
    MongoDB之聚合查询 MongoDB普通查询播客:https://blog.csdn.net/sinat_32366329/article/details/81784562 聚合框架是MongoDB的高级查询语言,允许我们通过转化合并由多个文档的数据来生成新的在单个文档里不存在...

    MongoDB之聚合查询

    MongoDB普通查询播客:https://blog.csdn.net/sinat_32366329/article/details/81784562

    聚合框架是MongoDB的高级查询语言,允许我们通过转化合并由多个文档的数据来生成新的在单个文档里不存在的文档信息。通俗一点来说,可以把MongoDB的聚合查询等价于SQL的GROUP BY语句。

    聚合操作过程可以理解为下面的图,每个聚合操作完后,将输出数据作为下一个聚合操作的输入数据。

    聚合操作汇总

     

    SQL对比聚合操作

     

    $match查询条件聚合操作

    普通的查询操作,对于查询用户名为jack的用户,使用find操作

    聚合的查询操作,使用aggregate操作。Aggregate单词的意思是聚合,可以增加多个操作,这里使用简单的条件,$match。注意aggregate内部使用数组,因为聚合操作可以聚合多个。

     

    $project,指定要输出的文档属性

    普通操作对于查询后需要输出指定的对象操作如下:

    $project聚合操作,指定要输出的文档属性

     

    $group用于聚合管道

     

    $match/$sort/$skip/$limit

    这4个操作符和普通查询函数意思相同,但是用法不同而已,普通查询通过点缀的方式连接函数。

    聚合操作则通过管道方式执行

     

    $unwind,将数组里面的每一个值,解析为一个文档

    普通查询,以及输出结果。结果like是一个数组

    $unwind解析为单个文档对象后,结果like是一个一个文档,要对应上属性。

     

    $out,将结果保存到另外一个集合中。这个对于集合迁移非常有用。

    目前数据库中只有以下3个集合。

    通过查询结果不使用$out输出到其它集合中

    执行以下结果,将输出的结果通过$out输出到like集合中。这时候like不存在会自己创建

    查看数据库中全部集合,多了一个like的集合

    查询like集合的结果

     

    结果重塑文档

             重塑文档,就是在文档查询结果返回的时候,利用mongodb提供的函数对文档处理,而不用读取到数据后人工代码去干预。

    字符串函数

    简单使用几个函数,其它函数都是大同小异的用法

    算术运算函数

    日期函数

    逻辑函数

    集合函数

    其它函数

    关注微信公众号(程序员小兔)不定期分享技术

    展开全文
  • ES聚合查询桶聚合

    2020-10-21 15:35:52
    文章目录ElasticSearch(springBoot):ElesticsearchTemple(ElasticsearchOperations)聚合查询示例一、Elasticsearch聚合1、TermsAggregation聚合(相当于mysql groupBy)2、聚合内继续聚合3、执行聚合查询总结 ...

    ElasticSearch(springBoot):

    ElesticsearchTemple(ElasticsearchOperations)聚合查询示例

    一、Elasticsearch聚合

    1、TermsAggregation聚合(相当于mysql groupBy)

    es有很多聚合,这里简单讲一下关键字聚合
    TermsAggregationBuilder grade_termsAggregationBuilder = AggregationBuilders.terms(“gradeNumberGroupBy”/* 聚合名称任意*/).field(“gradeNumber/根据那个字段分组与es对应字段相同/”).size(20/设置查询字段最多有多少不同的值,默认是10/);
    代码如下(示例):

    // 按年级分组,统计每个年级人数
    TermsAggregationBuilder grade_termsAggregationBuilder = AggregationBuilders.terms("gradeNumberGroupBy"/* 聚合名称任意*/).field("gradeNumber/*根据那个字段分组与es对应字段相同*/").size(20/*设置查询字段最多有多少不同的值,默认是10*/);
    // 按性别分组,统计男女比例
    TermsAggregationBuilder sex_termsAggregationBuilder = AggregationBuilders.terms("sex").field("sex");
    
    // 按民族分组,统计个民族比例
    TermsAggregationBuilder nationality_termsAggregationBuilder = AggregationBuilders.terms("nationality").field("nationality").size(58);
    aggrList.add(nationality_termsAggregationBuilder);
    
    
    

    2、聚合内继续聚合

    es聚合可内部继续嵌套其他聚合
    代码如下(示例):
    统计每个年级的男女比例

    // 按年级分组,统计每个年级人数
    TermsAggregationBuilder grade_termsAggregationBuilder = AggregationBuilders.terms("gradeNumberGroupBy"/* 聚合名称任意*/).field("gradeNumber/*根据那个字段分组与es对应字段相同*/").size(20/*设置查询字段最多有多少不同的值,默认是10*/);
    // 按性别分组,统计男女比例
    TermsAggregationBuilder sex_termsAggregationBuilder = AggregationBuilders.terms("sex").field("sex");
    grade_termsAggregationBuilder.subAggregation(sex_termsAggregationBuilder);
    

    3、执行聚合查询

    将之前准备的聚合条件加入nativeSearchQueryBuilder,使用elasticsearchOperations.search执行查询

    代码如下(示例):

    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
    nativeSearchQueryBuilder.addAggregation(grade_termsAggregationBuilder );
    // nativeSearchQueryBuilder.withQuery(boolQueryBuilder); // 添加数据筛选条件,在es基础查询中有介绍,可参考(比如想只查2020年入学的学生,可在这里加bool查询条件)
    NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
    nativeSearchQuery.setMaxResults(0); // 设置返回文本数,做聚合查询主要是做统计,这里不需要获取具体的哪些记录,故设为0
    
    Aggregations aggregations = this.elasticsearchOperations.search(nativeSearchQuery, Map.class, IndexCoordinates.of("es索引名称")).getAggregations();
    

    aggregations 中包含了聚合结果,层级结构有点复杂,后续需要将聚合结果转换成自己需要的结构,这里就不多讲了。

    注意:添加es配置后,elasticsearchOperations自动注入(可参考之前发布的文章)
    @Autowired
    public ElasticsearchOperations elasticsearchOperations;

    总结

    ExtendedStatsAggregationBuilder 聚合可以统计出count,min,max,avg,aum,平方和,方差,标准差,……等数据
    ES还有许多聚合,感兴趣可以研究一下

    展开全文
  • 主要介绍了JAVA mongodb 聚合几种查询方式详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 在本篇文章里小编给大家分享的是关于Django分组聚合查询实例内容,需要的朋友们可以参考下。
  • 4.ElasticSearch的高级复杂查询:非聚合查询聚合查询 这儿才是我今天要讲的重点。 4.1非聚合复杂查询(这儿展示了非聚合复杂查询的常用流程) public List<EsBlog> elasticSerchTest() {  //1.创建...

    1.springboot中配置elasticSearch

    1.1在工程中引入相关的jar包

     1.1.1 在build.gradle中添加需要的jar包

    我创建的gradle工程,对应的maven工程也是一样,添加对应的jar包即可

    // 添加  Spring Data Elasticsearch 的依赖
    compile('org.springframework.boot:spring-boot-starter-data-elasticsearch')
     
    // 添加  JNA 的依赖,java访问当前操作系统需要的包
    compile('net.java.dev.jna:jna:4.3.0')

    1.1.2在application.properties添加elasticsearch的配置

    #es的默认名称,如果安装es时没有做特殊的操作名字都是此名称
    spring.data.elasticsearch.cluster-name=elasticsearch
    # Elasticsearch 集群节点服务地址,用逗号分隔,如果没有指定其他就启动一个客户端节点,默认java访问端口9300
    spring.data.elasticsearch.cluster-nodes=localhost:9300
    # 设置连接超时时间
    spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s

    1.2创建文档实体对象

    package site.wlss.blog.domain.es;
     
    import java.io.Serializable;
    import java.sql.Timestamp;
     
    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.Document;
    import org.springframework.data.elasticsearch.annotations.Field;
    import org.springframework.data.elasticsearch.annotations.FieldIndex;
     
    import site.wlss.blog.domain.Blog;
     
     
    /**
     * EsBlog 文档类.
     * 
     * @since  2018年8月5日
     * @author wangli
     */
    /*@Document注解里面的几个属性,类比mysql的话是这样: 
        index –> DB 
        type –> Table 
        Document –> row 
    */
    @Document(indexName = "blog", type = "blog")
    public class EsBlog implements Serializable {
     
        private static final long serialVersionUID = 1L;
     
        @Id  // 主键,注意这个搜索是id类型是string,与我们常用的不同
        private String id;  //@Id注解加上后,在Elasticsearch里相应于该列就是主键了,在查询时就可以直接用主键查询
        @Field(index = FieldIndex.not_analyzed)  // 不做全文检索字段  
        private Long blogId; // Blog 实体的 id,这儿增加了一个blog的id属性
        private String title;
        private String summary;
        private String content;
        @Field(index = FieldIndex.not_analyzed)  // 不做全文检索字段  

    上面是我的部分代码,注意要对实体对象有个@Document注解,对象的id也有个@id的注解,其中还有个@Field的注解,这是对该字段的说明,下面对这些注解给出详细解释

    解释一:@Document注解

    @Document注解里面的几个属性,类比mysql的话是这样: 
    indexName –> 索引库的名称,建议以项目的名称命名,就相当于数据库DB
    type –> 类型,建议以实体的名称命名Table ,就相当于数据库中的表table
    Document –> row 就相当于某一个具体对象

    附上注解的内容:

    String indexName();//索引库的名称,建议以项目的名称命名
     
    String type() default "";//类型,建议以实体的名称命名
     
    short shards() default 5;//默认分区数
     
    short replicas() default 1;//每个分区默认的备份数
     
    String refreshInterval() default "1s";//刷新间隔
     
    String indexStoreType() default "fs";//索引文件存储类型

    解释二:@Id注解

    在Elasticsearch里相应于该列就是主键了,在查询时就可以直接用主键查询

    解释三:@Field注解

    public @interface Field {
     
    FieldType type() default FieldType.Auto;#自动检测属性的类型
     
    FieldIndex index() default FieldIndex.analyzed;#默认情况下分词
     
    DateFormat format() default DateFormat.none;
     
    String pattern() default "";
     
    boolean store() default false;#默认情况下不存储原文
     
    String searchAnalyzer() default "";#指定字段搜索时使用的分词器
     
    String indexAnalyzer() default "";#指定字段建立索引时指定的分词器
     
    String[] ignoreFields() default {};#如果某个字段需要被忽略
     
    boolean includeInParent() default false;
    
    }

    2.通过jpa创建文档库

    因为我们引入的是spring data的elasticsearch所以它遵循spring data的接口,也就是说操作elasticSearch与操作spring data jpa的方法是完全一样的,我们只将文档库继承ElasticsearchRepository即可。

    package site.wlss.blog.repository.es;
     
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
     
    import site.wlss.blog.domain.es.EsBlog;
     
     
    /**
     * EsBlog Repository接口.
     * @author Wang Li
     * @date 2018年8月5日
     */
    public interface EsBlogRepository extends ElasticsearchRepository<EsBlog, String> {
        //下面是我们根据 spring data jpa 的命名规范额外创建的两个查询方法
        /**
         * 模糊查询(去重),根据标题,简介,描述和标签查询(含有即可)Containing
         * @param title
         * @param Summary
         * @param content
         * @param tags
         * @param pageable
         * @return
         */
        Page<EsBlog> findDistinctEsBlogByTitleContainingOrSummaryContainingOrContentContainingOrTagsContaining(String title,String Summary,String content,String tags,Pageable pageable);
        
        /**
         * 根据 Blog 的id 查询 EsBlog
         * @param blogId
         * @return
         */
        EsBlog findByBlogId(Long blogId);
    }

    里面的内容是我根据spring data jpa 额外创建的两个方法。

    3.根据reporitory查询文档

    这个方法和操作jpa中的普通的方法没什么区别,就是普通的增删改查。

    4.ElasticSearch的高级复杂查询:非聚合查询和聚合查询

    这儿才是我今天要讲的重点。

    4.1非聚合复杂查询(这儿展示了非聚合复杂查询的常用流程)

    public List<EsBlog> elasticSerchTest() {
        //1.创建QueryBuilder(即设置查询条件)这儿创建的是组合查询(也叫多条件查询),后面会介绍更多的查询方法
        /*组合查询BoolQueryBuilder
            * must(QueryBuilders)   :AND
            * mustNot(QueryBuilders):NOT
            * should:               :OR
        */
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        //builder下有must、should以及mustNot 相当于sql中的and、or以及not
        
        //设置模糊搜索,博客的简诉中有学习两个字
        builder.must(QueryBuilders.fuzzyQuery("sumary", "学习"));
        
        //设置要查询博客的标题中含有关键字
        builder.must(new QueryStringQueryBuilder("man").field("springdemo"));
     
        //按照博客的评论数的排序是依次降低
        FieldSortBuilder sort = SortBuilders.fieldSort("commentSize").order(SortOrder.DESC);
     
        //设置分页(从第一页开始,一页显示10条)
        //注意开始是从0开始,有点类似sql中的方法limit 的查询
        PageRequest page = new PageRequest(0, 10);
     
        //2.构建查询
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //将搜索条件设置到构建中
        nativeSearchQueryBuilder.withQuery(builder);
        //将分页设置到构建中
        nativeSearchQueryBuilder.withPageable(page);
        //将排序设置到构建中
        nativeSearchQueryBuilder.withSort(sort);
        //生产NativeSearchQuery
        NativeSearchQuery query = nativeSearchQueryBuilder.build();
     
        //3.执行方法1
        Page<EsBlog> page = esBlogRepository.search(query);
        //执行方法2:注意,这儿执行的时候还有个方法那就是使用elasticsearchTemplate
        //执行方法2的时候需要加上注解
        //@Autowired
        //private ElasticsearchTemplate elasticsearchTemplate;
        List<EsBlog> blogList = elasticsearchTemplate.queryForList(query, EsBlog.class);
        
        //4.获取总条数(用于前端分页)
        int total = (int) page.getTotalElements();
     
        //5.获取查询到的数据内容(返回给前端)
        List<EsBlog> content = page.getContent();
     
        return content;
    }

    4.2查询条件QueryBuilder的构建方法举例

    在使用聚合查询之前我们有必要先来了解下创建查询条件QueryBuilder的几种常用方法

    4.2.1精确查询(必须完全匹配上)

    单个匹配termQuery

    //不分词查询 参数1: 字段名,参数2:字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词.
    QueryBuilder queryBuilder=QueryBuilders.termQuery("fieldName", "fieldlValue");
    //分词查询,采用默认的分词器
    QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("fieldName", "fieldlValue");

    多个匹配

    //不分词查询,参数1: 字段名,参数2:多个字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词.
    QueryBuilder queryBuilder=QueryBuilders.termsQuery("fieldName", "fieldlValue1","fieldlValue2...");
    //分词查询,采用默认的分词器
    QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery("fieldlValue", "fieldName1", "fieldName2", "fieldName3");
    //匹配所有文件,相当于就没有设置查询条件
    QueryBuilder queryBuilder=QueryBuilders.matchAllQuery();

    4.2.2模糊查询(只要包含即可)

    //模糊查询常见的5个方法如下
    //1.常用的字符串查询
    QueryBuilders.queryStringQuery("fieldValue").field("fieldName");//左右模糊
    //2.常用的用于推荐相似内容的查询
    QueryBuilders.moreLikeThisQuery(new String[] {"fieldName"}).addLikeText("pipeidhua");//如果不指定filedName,则默认全部,常用在相似内容的推荐上
    //3.前缀查询  如果字段没分词,就匹配整个字段前缀
    QueryBuilders.prefixQuery("fieldName","fieldValue");
    //4.fuzzy query:分词模糊查询,通过增加fuzziness模糊属性来查询,如能够匹配hotelName为tel前或后加一个字母的文档,fuzziness 的含义是检索的term 前后增加或减少n个单词的匹配查询
    QueryBuilders.fuzzyQuery("hotelName", "tel").fuzziness(Fuzziness.ONE);
    //5.wildcard query:通配符查询,支持* 任意字符串;?任意一个字符
    QueryBuilders.wildcardQuery("fieldName","ctr*");//前面是fieldname,后面是带匹配字符的字符串
    QueryBuilders.wildcardQuery("fieldName","c?r?");

    4.2.3范围查询

    //闭区间查询
    QueryBuilder queryBuilder0 = QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2");
    //开区间查询
    QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2").includeUpper(false).includeLower(false);//默认是true,也就是包含
    //大于
    QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("fieldName").gt("fieldValue");
    //大于等于
    QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("fieldName").gte("fieldValue");
    //小于
    QueryBuilder queryBuilder4 = QueryBuilders.rangeQuery("fieldName").lt("fieldValue");
    //小于等于
    QueryBuilder queryBuilder5 = QueryBuilders.rangeQuery("fieldName").lte("fieldValue");

    4.2.4组合查询/多条件查询/布尔查询

    QueryBuilders.boolQuery()
    QueryBuilders.boolQuery().must();//文档必须完全匹配条件,相当于and
    QueryBuilders.boolQuery().mustNot();//文档必须不匹配条件,相当于not
    QueryBuilders.boolQuery().should();//至少满足一个条件,这个文档就符合should,相当于or

    4.3聚合查询

    Elasticsearch有一个功能叫做 聚合(aggregations) ,它允许你在数据上生成复杂的分析统计。它很像SQL中的 GROUP BY 但是功能更强大。

    为了掌握聚合,你只需要了解两个主要概念:(参考https://blog.csdn.net/dm_vincent/article/details/42387161)

    Buckets(桶):满足某个条件的文档集合。

    Metrics(指标):为某个桶中的文档计算得到的统计信息。

    就是这样!每个聚合只是简单地由一个或者多个桶,零个或者多个指标组合而成。可以将它粗略地转换为SQL:

    SELECT COUNT(color) 
    FROM table
    GROUP BY color

    以上的COUNT(color)就相当于一个指标。GROUP BY color则相当于一个桶。

    桶和SQL中的组(Grouping)拥有相似的概念,而指标则与COUNT(),SUM(),MAX()等相似。

    让我们仔细看看这些概念。

    桶(Buckets)

    一个桶就是满足特定条件的一个文档集合:

    一名员工要么属于男性桶,或者女性桶。
    城市Albany属于New York州这个桶。
    日期2014-10-28属于十月份这个桶。
    随着聚合被执行,每份文档中的值会被计算来决定它们是否匹配了桶的条件。如果匹配成功,那么该文档会被置入该桶中,同时聚合会继续执行。

    桶也能够嵌套在其它桶中,能让你完成层次或者条件划分这些需求。比如,Cincinnati可以被放置在Ohio州这个桶中,而整个Ohio州则能够被放置在美国这个桶中。

    ES中有很多类型的桶,让你可以将文档通过多种方式进行划分(按小时,按最流行的词条,按年龄区间,按地理位置,以及更多)。但是从根本上,它们都根据相同的原理运作:按照条件对文档进行划分。

    指标(Metrics)

    桶能够让我们对文档进行有意义的划分,但是最终我们还是需要对每个桶中的文档进行某种指标计算。分桶是达到最终目的的手段:提供了对文档进行划分的方法,从而让你能够计算需要的指标。

    多数指标仅仅是简单的数学运算(比如,min,mean,max以及sum),它们使用文档中的值进行计算。在实际应用中,指标能够让你计算例如平均薪资,最高出售价格,或者百分之95的查询延迟。

    将两者结合起来

    一个聚合就是一些桶和指标的组合。一个聚合可以只有一个桶,或者一个指标,或者每样一个。在桶中甚至可以有多个嵌套的桶。比如,我们可以将文档按照其所属国家进行分桶,然后对每个桶计算其平均薪资(一个指标)。

    因为桶是可以嵌套的,我们能够实现一个更加复杂的聚合操作:

    1. 将文档按照国家进行分桶。(桶)
    2. 然后将每个国家的桶再按照性别分桶。(桶)
    3. 然后将每个性别的桶按照年龄区间进行分桶。(桶)
    4. 最后,为每个年龄区间计算平均薪资。(指标)

    聚合查询都是由AggregationBuilders创建的,一些常见的聚合查询如下

    (参考:http://blog.csdn.net/u010454030/article/details/63266035)

    (1)统计某个字段的数量
      ValueCountBuilder vcb=  AggregationBuilders.count("count_uid").field("uid");
    (2)去重统计某个字段的数量(有少量误差)
     CardinalityBuilder cb= AggregationBuilders.cardinality("distinct_count_uid").field("uid");
    (3)聚合过滤
    FilterAggregationBuilder fab= AggregationBuilders.filter("uid_filter").filter(QueryBuilders.queryStringQuery("uid:001"));
    (4)按某个字段分组
    TermsBuilder tb=  AggregationBuilders.terms("group_name").field("name");
    (5)求和
    SumBuilder  sumBuilder=    AggregationBuilders.sum("sum_price").field("price");
    (6)求平均
    AvgBuilder ab= AggregationBuilders.avg("avg_price").field("price");
    (7)求最大值
    MaxBuilder mb= AggregationBuilders.max("max_price").field("price"); 
    (8)求最小值
    MinBuilder min=    AggregationBuilders.min("min_price").field("price");
    (9)按日期间隔分组
    DateHistogramBuilder dhb= AggregationBuilders.dateHistogram("dh").field("date");
    (10)获取聚合里面的结果
    TopHitsBuilder thb=  AggregationBuilders.topHits("top_result");
    (11)嵌套的聚合
    NestedBuilder nb= AggregationBuilders.nested("negsted_path").path("quests");
    (12)反转嵌套
    AggregationBuilders.reverseNested("res_negsted").path("kps ");

    聚合查询的详细使用步骤如下:

    public void test(){
        //目标:搜索写博客写得最多的用户(一个博客对应一个用户),通过搜索博客中的用户名的频次来达到想要的结果
        //首先新建一个用于存储数据的集合
        List<String> ueserNameList=new ArrayList<>();
        //1.创建查询条件,也就是QueryBuild
        QueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();//设置查询所有,相当于不设置查询条件
        //2.构建查询
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //2.0 设置QueryBuilder
        nativeSearchQueryBuilder.withQuery(matchAllQuery);
        //2.1设置搜索类型,默认值就是QUERY_THEN_FETCH,参考https://blog.csdn.net/wulex/article/details/71081042
        nativeSearchQueryBuilder.withSearchType(SearchType.QUERY_THEN_FETCH);//指定索引的类型,只先从各分片中查询匹配的文档,再重新排序和排名,取前size个文档
        //2.2指定索引库和文档类型
        nativeSearchQueryBuilder.withIndices("myBlog").withTypes("blog");//指定要查询的索引库的名称和类型,其实就是我们文档@Document中设置的indedName和type
        //2.3重点来了!!!指定聚合函数,本例中以某个字段分组聚合为例(可根据你自己的聚合查询需求设置)
        //该聚合函数解释:计算该字段(假设为username)在所有文档中的出现频次,并按照降序排名(常用于某个字段的热度排名)
        TermsBuilder termsAggregation = AggregationBuilders.terms("给聚合查询取的名").field("username").order(Terms.Order.count(false));
        nativeSearchQueryBuilder.addAggregation(termsAggregation);
        //2.4构建查询对象
        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        //3.执行查询
        //3.1方法1,通过reporitory执行查询,获得有Page包装了的结果集
        Page<EsBlog> search = esBlogRepository.search(nativeSearchQuery);
        List<EsBlog> content = search.getContent();
        for (EsBlog esBlog : content) {
            ueserNameList.add(esBlog.getUsername());
        }
        //获得对应的文档之后我就可以获得该文档的作者,那么就可以查出最热门用户了
        //3.2方法2,通过elasticSearch模板elasticsearchTemplate.queryForList方法查询
        List<EsBlog> queryForList = elasticsearchTemplate.queryForList(nativeSearchQuery, EsBlog.class);
        //3.3方法3,通过elasticSearch模板elasticsearchTemplate.query()方法查询,获得聚合(常用)
        Aggregations aggregations = elasticsearchTemplate.query(nativeSearchQuery, new ResultsExtractor<Aggregations>() {
            @Override
            public Aggregations extract(SearchResponse response) {
                return response.getAggregations();
            }
        });
        //转换成map集合
        Map<String, Aggregation> aggregationMap = aggregations.asMap();
        //获得对应的聚合函数的聚合子类,该聚合子类也是个map集合,里面的value就是桶Bucket,我们要获得Bucket
        StringTerms stringTerms = (StringTerms) aggregationMap.get("给聚合查询取的名");
        //获得所有的桶
        List<Bucket> buckets = stringTerms.getBuckets();
        //将集合转换成迭代器遍历桶,当然如果你不删除buckets中的元素,直接foreach遍历就可以了
        Iterator<Bucket> iterator = buckets.iterator();
        
        while(iterator.hasNext()) {
            //bucket桶也是一个map对象,我们取它的key值就可以了
            String username = iterator.next().getKeyAsString();//或者bucket.getKey().toString();
            //根据username去结果中查询即可对应的文档,添加存储数据的集合
            ueserNameList.add(username);
        }
        //最后根据ueserNameList搜索对应的结果集
        List<User> listUsersByUsernames = userService.listUsersByUsernames(ueserNameList);
    }

    原文地址:https://blog.csdn.net/topdandan/article/details/81436141

    展开全文
  • 微信小程序 聚合查询

    千次阅读 2021-01-05 17:44:25
    //普通数据查询 db.collection("china") //获取集合china的引用 .where({ //查询的条件操作符where gdp: _.gt(3000) //查询筛选条件,gt表示字段需大于指定值。 }) .field({ //显示哪些字段 _id:false, //默认...
  • 一、ES的demo数据如下: 二、简单聚合,获得平均分 GET /student/student/_search { "aggs": { "avg_score": { "avg": { "field": "score" } } } } 查询结果: ... * 聚合查询avg * *GET /s...
  • Solr聚合查询

    万次阅读 2017-07-25 21:33:06
    1 分组查询 1.1 Facet分组 solr种以导航为目的的查询结果成为facet,在用户查询的结果上根据分类增加了count信息,然后用户根据count信息做进一步搜索,  Facet是solr的高级搜索功能之一,可以给用户提供更友好的...
  • ES(四)ES使用(基本查询、聚合查询

    万次阅读 多人点赞 2019-01-08 22:31:50
    { 'query_string':{ 'query':'title:crime^10 +title:punishment -otitle:cat +author:(+Fyodor +dostoevsky)' } } } 聚合查询 聚合提供了用户进行分组和数理统计的能力,可以把聚合理解成SQL中的GROUP BY和分组函数...
  • Elasticsearch7.x DSL语法之聚合查询

    千次阅读 2020-12-28 16:02:57
    聚合查询是开发中常见的场景,一般包含。求和、最大值、最小值、平均值、总记录数等。 注意事项:text类型是不支持聚合的。 1.1.初始测试数据 学习SQL中常用的案例,老师信息表 字段信息:name(姓名) | age(年龄) | ...
  • 集合查询 ...: 0, //表示查询多少条文档,聚合只需就和结果,输出文档可以设置为0条 &amp;quot;aggs&amp;quot;: { &amp;quot;price_of_sum&amp;quot;: { //自行取名作为结果集
  • script": { "buckets_path": { "p1": "sum_real", "p2": "sum_cost" }, "script": "((params.p1 - params.p2) / params.p2)", "format": "0.000" } } } } } } 3.java 实现,只提供了聚合查询用到的代码.具体逻辑都各...
  • Elasticsearch --- 聚合查询(一)

    万次阅读 2020-09-16 11:03:48
    我们也可以实现同样的功能,聚合有关资料官方文档内容较多,这里大概分两篇博客写这个有关Elasticsearch聚合。 官方对聚合有四个关键字:Metric(指标)、Bucketing(桶)、Matrix(矩阵)、Pipeline(管道)。 一、...
  • 简介:⼿把⼿玩转es的聚合查询之指标聚合 ES聚合分析 聚合分析是数据库中重要的功能特性,完成对⼀个查询的数据集中数据的聚合计算,如:找出某字段(或计算表达式的结果)的最⼤值、最⼩值,计算和、平均值等。ES...
  • TP5聚合查询

    2019-04-10 10:52:49
    #模型的聚合,对应函数搭配函数进行聚合查询 $res=Player::count();//获取数据条数 $res=Player::where('p_id','<',5) ->count(); $res=Player::max('p_num');//获取最大 $res=Player::where('p_id','&...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 206,093
精华内容 82,437
关键字:

聚合查询