Elasticsearch 基本使用(四)聚合查询

本文介绍了Elasticsearch中的聚合查询功能,包括单字段聚合查询,按年龄和城市进行分组,并展示了如何统计分组数量、计算平均值、总金额和最大值。对于文本字段,需要使用关键字字段进行分组。此外,文章还讲解了如何进行多字段聚合查询,以及如何自定义聚合结果的排序。
摘要由CSDN通过智能技术生成

概述

说到聚合查询,马上会想到 SQL 中的 group by,ES中也有类似的功能,名叫 Aggregation。

单字段聚合查询

统计分组后的数量

按年龄分组,然后统计每个年龄人数 count(*) ,age xxx group by age

非文档字段分组
GET bank/_search
{
  "aggs": {
    "by_age": {
      "terms": {
      # age 为数值,可以直接分组
        "field": "age"
      }
    }
  }
}
文档字段分组
GET bank/_search
{
  "aggs": {
    "by_age": {
      "terms": {
        "field": "city"
      }
    }
  }
}

直接使用文档字段分组会报错。
在这里插入图片描述
ES没有对文本字段聚合,排序等操作优化;如果对文本字段进行分组,推荐使用 关键字字段
改为关键字分组

GET bank/_search
{
  "aggs": {
    "by_age": {
      "terms": {
        "field": "city.keyword"
      }
    }
  }
}

在这里插入图片描述
但是,ES默认只返回10条分组数据;如果要返回更多分组数据,需要在聚合里面使用 size 字段

GET bank/_search
{
  "aggs": {
    "by_age": {
      "terms": {
        "field": "city.keyword",
        "size": 1000
      }
    }
  }
}

可以看到,返回了更多的分组数据
在这里插入图片描述

其他聚合运算

在使用 terms时,ES会根据指定字段进行分组;此时得到的结果集是

"buckets" : [
        {
          "key" : 分组字段的值,
          "doc_count" : 当前分组数量
        }
]        
统计平均值

如果,我们要基于当前分组,进行其他聚合运算呢。
比如,我按照年龄分组,统计数量;
然后我要统计每个分组内,账户余额的平均值呢。

# 基于年龄分组的基础上,统计账户余额平均值
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}
统计总金额

如果还要基于账户余额平均值的基础上,还要进行其他聚合运算,可以直接在 内部的 aggs 内添加其他聚合函数。比如,我不仅要统计平均值,还要统计每个分组内的账户总金额。

# 基于统计账户余额平均值的基础上,再统计每个分组下,账户总金额
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        },
        "sum_balance":{
          "sum": {
            "field": "balance"
          }
        }
      }
    }
  }
}
统计最大值

再统计一个,基于年龄的分组下,账户余额的最大值

# 基于统计账户余额平均值和总金额的基础上,再统计每个分组下,账户最大余额
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        },
        "sum_balance":{
          "sum": {
            "field": "balance"
          }
        },
        "max_balance":{
          "max": {
            "field": "balance"
          }
        }
      }
    }
  }
}
自定义聚合结果排序

默认,ES的聚合以分组内数量倒序排序。
我们基于上面最后的统计结果,自定义聚合结果排序

  • 默认排序方式
    在这里插入图片描述
  • 按数量升序
    之前说过,默认分组,提供了两个字段的返回;
    key 和 doc_count,如果要自定义这两个基本字段排序方式,需要在前面加上 下划线 _当然还可以按照其他聚合函数的结果排序
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000,
        "order": {
        # 数量升序/降序
          "_count": "asc/desc"
          # key 升序/降序
          "_key": "asc/desc",
          # 按平均值升序/降序
          "avg_balance":"asc/desc",
          # 按总金额值升序/降序
          "sum_balance":"asc/desc",
          # 按最大值升序/降序
          "max_balance":"asc/desc",
        }
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        },
        "sum_balance":{
          "sum": {
            "field": "balance"
          }
        },
        "max_balance":{
          "max": {
            "field": "balance"
          }
        }
      }
    }
  }
}
简单聚合小结

总之,一句话。
分组逻辑在外面的 aggs,使用的是 terms 指定分组字段;默认,附带每个分组内数量统计。
基于此分组的其他聚合运算,aggs 内再定义一个 aggs,用于定义其他聚合运算。
自定义聚合结果排序,在aggs -> terms 下使用 order 指定排序字段及其排序方式,但是,经过测试,直接写多个字段排序时,只有最后一个生效

多字段聚合查询

上面的聚合查询,我们都是基于一个字段进行查询。
那么如何实现按多个字段进行分组呢?

我们先看看,在上面额外聚合运算上使用 terms 的效果

  • 先对 age分组,再对gender(文档字段,需使用关键字形式)分组,看看效果
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_age": {
      "terms": {
        "field": "age",
        "size": 1000,
        "order": {
          "_count": "desc"
        }
      },
      "aggs": {
        "by_gender":{
          "terms": {
            "field": "gender.keyword",
            "size": 1000
          }
        }
        
      }
    }
  }
}

在这里插入图片描述
可以看到,得到的结果是一个带有层级结构的数据,这在某些场景下可能有用;但常规的多字段分组可不是这样的,我们通常需要一个扁平化的排序结果

  • 使用 script 替代 field ,定义分组字段
    script :使用脚本,运算一个结果来作为分组字段。
    使用以下 脚本替代 field
    "script": {
        "inline": "doc['age'].value +'-'+ doc['gender.keyword'].value "
    }
    

以上脚本的意思是,使用 age-gender 作为分组依据,注意,这里依然要注意文档字段 .keyword 的问题,以下是完整脚本

# 按多个字段分组,这里按照 年龄-性别 分组,不能直接使用 field 分组,要使用 script 构建分组内容;按默认的数量倒序
GET bank/_search
{
  "size": 0, 
  "aggs": {
    "by_state": {
      "terms": {
        "script": {
                    "inline": "doc['age'].value +'-'+ doc['gender.keyword'].value "
                },
        "size": 1000,
        "order": {
          "_count": "desc"
        }
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        },
        "sum_balance":{
          "sum": {
            "field": "balance"
          }
        },
        "max_balance":{
          "max": {
            "field": "balance"
          }
        }
      }
    }
  }
}

可以看到,按照预期进行了分组
在这里插入图片描述
至于基于分组的其他聚合运算,排序等操作,和单字段分组一样。

### 回答1: Java ESElasticsearch聚合查询是一种在Java开发中使用Elasticsearch进行聚合分析的方法。 聚合查询是指对数据进行统计分析,例如计算最大值、最小值、平均值、总和等。Java ES提供了丰富的聚合查询功能,可进行多层次、多字段的聚合计算。 在Java中使用Elasticsearch进行聚合查询,首先需要创建一个Elasticsearch客户端连接,获取到与Elasticsearch集群的通信管道。 然后,使用Java代码构建聚合查询请求。聚合查询的请求是基于JSON结构的DSL查询语言,可以使用Java提供的相关工具类来构建查询请求。 聚合查询请求中包含了聚合的类型(例如求和、平均值等)、聚合的字段、聚合的范围(例如按某个字段进行分组)等参数。 构建好查询请求后,通过客户端发送请求到Elasticsearch集群,并获取返回的查询结果。 最后,解析返回的查询结果,获取到聚合计算的结果数据,可以进一步进行业务处理或展示。 通过Java ES聚合查询,我们可以灵活地对大规模数据进行聚合分析,从中挖掘出有价值的信息,为业务决策提供支持。同时,Java ES的分布式计算能力也保证了聚合查询在大规模数据集上的高效执行。 总之,Java ES聚合查询是一种使用Java语言与Elasticsearch集群进行交互,进行多维度、多层次聚合计算的方法,能够帮助开发者快速获取到数据统计结果,为业务分析提供数据支持。 ### 回答2: Java ESElasticsearch)是一个基于Java开发的开源搜索引擎,它能够以高效的方式存储、搜索和分析大量的数据。 聚合查询是Java ES中的一种重要功能,它可以帮助我们以更灵活的方式对数据进行聚合和分析,从而得出有价值的业务洞察。聚合查询可以对数据进行分组、排序、统计和过滤等操作,使我们能够深入了解数据的特征和趋势。 聚合查询可以针对多个字段进行聚合操作,比如求和、平均值、最大值、最小值等。它还支持桶聚合,可以将数据按照指定的条件进行分组,比如按照地区、时间段、类别等进行分组统计分析。此外,聚合查询还可以进行嵌套聚合,即在一个聚合查询中嵌套另一个聚合查询进行进一步的分析。 在Java ES使用聚合查询十分简单,首先需要建立一个Elasticsearch客户端连接,然后准备查询DSL语句,通过调用相关API进行查询。聚合查询的结果以JSON格式返回,我们可以解析这些结果并进行业务处理。 总之,Java ES聚合查询功能提供了丰富的数据分析能力,能够满足不同业务场景的需求。通过聚合查询,我们可以更轻松地理解和挖掘数据的潜在价值,为业务决策和优化提供有力支持。 ### 回答3: Java ESElasticsearch聚合查询是一种用于分析和统计数据的功能。聚合查询可以对索引中的数据进行分组、筛选、计数和计算。 首先,聚合查询可以根据指定的字段将数据分组。例如,可以按照地区将销售数据进行分组,然后统计每个地区的销售额、订单数量等信息。 其次,聚合查询还可以根据一定的条件对数据进行筛选。例如,可以筛选出销售额大于10000的地区,或者筛选出销售数量超过100的产品类别。 除了基本的分组和筛选功能,聚合查询还支持各种常用的统计计算。例如,可以计算每个地区的销售额总和、平均值、最大值、最小值等。还可以计算每个月的销售额趋势和增长率等统计信息。 此外,聚合查询还支持多种聚合函数的组合和嵌套。例如,可以先按地区分组,然后在每个地区内再按销售年份进行分组,最后计算每个地区每年的销售额总和或平均值等。 Java ES聚合查询功能强大且灵活,可以满足各种复杂的统计分析需求。通过灵活的组合和嵌套,可以得到更详细和全面的统计结果,为数据分析和决策提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值