Elasticsearch7.x DSL语法之聚合查询

程序员小强总结的 ElasticSearch专题超全总结篇在这里:传送门
结合官网资料,做了更详细的实际使用总结。
从单机版安装到集群高可用生产环境搭建、基本概念(索引,分片,节点,倒排索引…)、DSL语法实践、分词器(内置+中文)、SpringBoot整合实战、仿京东商品搜索实战实现。

1.前言

聚合查询是开发中常见的场景,一般包含。求和、最大值、最小值、平均值、总记录数等。

注意事项:text类型是不支持聚合的。

1.1.初始测试数据

学习SQL中常用的案例,老师信息表
字段信息:name(姓名) | age(年龄) | job(工作岗位) | sex(性别1-男,2-女) | salary(薪资)

#老师信息
#注:每个岗位都是神圣的,以下测试数据,纯属虚构,仅测试需要
PUT /teacher_info/_bulk
{ "index" : {  "_id" : "101" } }
{ "name" : "Tom","age":32,"job":"Math","sex":1,"salary": 3000 }
{ "index" : {  "_id" : "102" } }
{ "name" : "Zhangsan","age":22,"job":"Java","sex":1,"salary": 5000}
{ "index" : {  "_id" : "103" } }
{ "name" : "lisi","age":29,"job":"sports","sex":1,"salary": 4000 }
{ "index" : {  "_id" : "104" } }
{ "name" : "wangwu","age":25,"job":"sports","sex":1,"salary": 4300}
{ "index" : {  "_id" : "105" } }
{ "name" : "Mary","age":30,"job":"H5","sex":2,"salary": 4800}
{ "index" : {  "_id" : "106" } }
{ "name" : "Luccy","age":33,"job":"English","sex":2,"salary": 5500 }
{ "index" : {  "_id" : "107" } }
{ "name" : "Xiaomei","age":23,"job":"English","sex":2,"salary": 5800 }
{ "index" : {  "_id" : "108" } }
{ "name" : "Xiaogao","age":27,"job":"Php","sex":1,"salary": 3900}
{ "index" : {  "_id" : "109" } }
{ "name" : "Dabai","age":26,"job":"Chinese","sex":1,"salary": 4000 }
{ "index" : {  "_id" : "110" } }
{ "name" : "Xiaowei","age":25,"job":"C++","sex":1,"salary": 4500 }

1.2.ES聚合分析查询的写法

在查询请求体中以aggregations节点语法如下:**

"aggregations" : {
    "<aggregation_name>" : {                                 <!--聚合的名字 -->
        "<aggregation_type>" : {                             <!--聚合的类型 -->
            <aggregation_body>                               <!--聚合体:对哪些字段进行聚合 -->
        }
        [,"meta" : {  [<meta_data_body>] } ]?                <!--元 -->
        [,"aggregations" : { [<sub_aggregation>]+ } ]?       <!--在聚合里面在定义子聚合 -->
    }
}

注:aggregations 也可简写为 aggs

2.求和(Sum)

案例:求所有老师的薪资总和
注:“size”: 0 ,参数表示不用返回文档列表,只返回汇总的数据即可

GET teacher_info/_search
{
  "size": 0,
  "aggs": {
    "sum_salary": {
      "sum": {
        "field":"salary"
      }
    }
  }
}

在这里插入图片描述

3.最大值(Max)

示例:求薪资最大值

GET teacher_info/_search
{
  "size": 0,
  "aggs": {
    "max_salary": {
      "max": {
        "field":"salary"
      }
    }
  }
}

4.最小值(Min)

案例:求薪资最低值

GET teacher_info/_search
{
  "size": 0,
  "aggs": {
    "min_salary": {
      "min": {
        "field":"salary"
      }
    }
  }
}

5.平均值(Avg)

案例:求薪资平均值

GET teacher_info/_search
{
  "size": 0,
  "aggs": {
    "avg_salary": {
      "avg": {
        "field":"salary"
      }
    }
  }
}

6.去重数值(cardinality)

类似mysql的 count distinct
案例:老师一共教了多少学科

GET teacher_info/_search
{
    "size": 0,
    "aggs" : {
        "job_count" : {
            "cardinality" : {
                "field" : "job.keyword"
            }
        }
    }
}

由于在创建索引的时候,没有先创建Mapping, job这个字段默认是 text类型,而聚合统计不知道text类型,
所以这里需要使用“job.keyword”
在这里插入图片描述

字符串类型的参数,在没有指定mapping的情况下,默认生成的类型如上图。
在这里插入图片描述

7.多值查询-最大最小和平均值

案例:查询最低、最高和平均工资

GET teacher_info/_search
{
  "size": 0,
  "aggs": {
    "max_salary": {
      "max": {
        "field": "salary"
      }
    },
    "min_salary": {
      "min": {
        "field": "salary"
      }
    },
    "avg_salary": {
      "avg": {
        "field": "salary"
      }
    }
  }
}

在这里插入图片描述

8.返回多个聚合值(Status)

stats 统计,请求后会直接显示多种聚合结果,总记录数,最大值,最小值,平均值,汇总值

GET employees_info/_search
{
  "size": 0,
  "aggs": {
    "salary_stats": {
      "stats": {
        "field":"salary"
      }
    }
  }
}

在这里插入图片描述

9.百分比(Percentiles)

对指定字段的值按从小到大累计每个值对应的文档数的占比,返回指定占比比例对应的值。**

GET teacher_info/_search
{
  "size": 0,
  "aggs": {
    "age_percentiles": {
      "percentiles": {
        "field": "age"
      }
    }
  }
}

默认按照[ 1, 5, 25, 50, 75, 95, 99 ]来统计
在这里插入图片描述

返回结果可以理解为:占比为25%的文档的age值 <= 25,或反过来:age<=25的文档数占总命中文档数的25%
因为是默认返回的 ,[ 1, 5, 25, 50, 75, 95, 99 ] 所以 可能存在重复值

key-value形式返回
添加参数"keyed": false
在这里插入图片描述

10.文档值占比(Percentile Ranks)

这里指定值,查占比。注意占比是小于文档值的比例

GET teacher_info/_search
{
    "size": 0,
    "aggs" : {
        "age_percentiles" : {
            "percentile_ranks" : {
                "field" : "age", 
                "values" : [ 22, 25, 33]
            }
        }
    }
}

下图含义

  • 小于age<=22的占比 5%
  • 小于age<=25的占比 30%
  • 小于age<=33的占比 100%
    在这里插入图片描述

11.中位数查询

案例:求工资中位数

POST teacher_info/_search
{
    "size": 0,
    "aggs": {
        "load_time_outlier": {
            "percentiles": {
                "field": "salary",
                "percents" : [ 50, 99],
                "keyed": false
            }
        }
    }
}

在这里插入图片描述

12.分组取Top N 之(Top Hits)

案例1:根据性别分组。展示工资排名top3

GET /teacher_info/_search?size=0
{
    "aggs": {
        "top_tags": {
            "terms": {
                "field": "sex"
            },
            "aggs": {
                "top_sales_hits": {
                    "top_hits": {
                        "sort": [
                            {
                                "salary": {
                                    "order": "desc"
                                }
                            }
                        ],
                        "_source": {
                            "includes": [ "name", "sex","salary" ]
                        },
                        "size" : 3
                    }
                }
            }
        }
    }
}

在这里插入图片描述

13.分组之聚合

案例:根据性别分组求平均工资

GET /teacher_info/_search
{
  "size":0,
  "aggs": {
    "top_tags": {
      "terms": {
        "field": "sex"
      },
      "aggs": {
        "avg_salary": {
          "avg": {
            "field": "salary"
          }
        }
      }
    }
  }
}

14.总记录数查询

类似mysql的count

#方式1:统计年龄 >=25 的记录数
GET teacher_info/_count
{
  "query": {
    "range": {
      "age":{
        "gte": 25
      }
    }
  }
}

#方式2:统计年龄 >=25 的记录数
GET teacher_info/_search?size=0
{
  "query": {
    "range": {
      "age":{
        "gte": 25
      }
    }
  }
}

在这里插入图片描述

附录

官方示例:传送门

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Elasticsearch DSL语法是一种用于构建Elasticsearch查询的Python库。它提供了一种简单而强大的方式来构建复杂的查询和聚合操作。DSL语法使用Python的面向对象语法来构建查询,使得代码易于阅读和维护。它支持各种查询类型,包括全文搜索、范围查询、过滤器、聚合等。DSL语法还提供了一些方便的方法来处理查询结果,如分页、排序、高亮等。总之,Elasticsearch DSL语法是一个非常有用的工具,可以帮助开发人员更轻松地构建和执行Elasticsearch查询。 ### 回答2: Elasticsearch DSL是一个基于Python的模块,它允许用户以更加方便的方式与Elasticsearch交互。DSL提供了一种更加简洁和可读的语法,减少了编写Elasticsearch查询的复杂性。DSL语法旨在尽可能地呈现Elasticsearch查询的结构。 DSL的主要语法包括以下几个方面: 1.索引:在DSL中,用户需要指定要查询的索引。例如,要查询名为“movies”的索引,用户应该使用以下语法:Index('movies')。 2.查询:设置检索的查询条件。在DSL中,用户可以使用各种查询类型来设置这些条件,例如term,match,range等。例如,要查询字段“title”等于“The Godfather”的文档,用户可以使用以下代码: from elasticsearch_dsl import Search from elasticsearch_dsl.query import Term s = Search().filter(Term(title='The Godfather')) 3.聚合:查询结果的聚合是DSL可以处理的另一个重要方面。用户可以使用各种聚合类型来获得有关查询结果的统计信息,例如总数,平均值,最大值等。例如,要统计字段“rating”的平均值,用户可以使用以下代码: from elasticsearch_dsl import Search from elasticsearch_dsl.aggs import Avg s = Search().agg(Avg('avg_rating', field='rating')) 4.排序:DSL中的排序允许用户根据指定的字段对查询结果进行排序。用户可以使用“sort”方法来设置排序规则,如以下代码所示: from elasticsearch_dsl import Search s = Search().sort('rating') 总之,Elasticsearch DSL语法提供了更强大的、更方便的方式与Elasticsearch进行交互。无论是搜索、聚合还是排序,DSL都可以帮助用户更加简单地构建复杂的查询。 ### 回答3: Elasticsearch DSL(Domain-Specific Language)是 Elasticsearch Python 客户端库实现的一种流畅的Python语法查询语句。Elasticsearch DSL 使Python开发人员能够以简单、易读的方式与 Elasticsearch 进行交互,更加方便地构建复杂的查询语句和聚合操作。下面我将从 dsl 查询语句的特点、基本语法和示例等方面进行详细说明。 Elasticsearch DSL查询语句的特点: 1.以Python方式编写查询语法,更加清晰易读; 2.类似于SQL语句的查询结构,更容易学习和使用; 3.高效的性能和精确的结果,提高了开发效率和用户体验; 4.可以轻松地与Python中的其他库进行集成,增加了开发的灵活性和可扩展性。 Elasticsearch DSL查询语句的基本语法: 1.创建一个查询: from elasticsearch_dsl import Search client = Elasticsearch() # 创建 Elasticsearch 客户端对象 search = Search(using=client) 2.匹配所有文档: search = Search(using=client, index="index_name").query("match_all") 3.匹配查询: search = Search(using=client, index="index_name").query("match", field="value") 4.范围查询: search = Search(using=client, index="index_name").query("range", field={"gte": 10, "lte":20}) 5.多个条件查询: search = Search(using=client, index="index_name").query("bool", must=[Q("match", title="python"), Q("match", content="elasticsearch")]) 6.结果排序和分页查询: search = Search(using=client, index="index_name").query("match", title="python").sort("-date").[0:10] Elasticsearch DSL查询语句示例: 1.查询内容为"python"的文章列表,并按发布时间倒序排序进行分页: s = Search().query("match", title="python").sort("-date").[0:10] response = s.execute() for hit in response: print(hit.title) 2.将通配符查询添加到筛选器列表中: search = Search().filter("wildcard", title="p*").query("match", body="python") response = search.execute() print("Total hits: ", response.hits.total.value) 3.使用子查询搜索不同版本的一个索引: s = Search(index="my-index").query( "bool", must_not=[Q("match", title="python")], should=[Q("match", title="java"), Q("match", title="ruby")] )执行 response = s.execute() print(response.hits.total.value) 总结:Elasticsearch DSL提供了Python化的语法来方便用户进行 Elasticsearch 操作。通过简单的语句即可实现复杂的查询,提高了开发效率和用户体验,开发人员可以很快学会并使用 Elasticsearch DSL

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值