Elasticsearch聚合学习之四:结果排序

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 在前面的实战中,聚合的结果以桶(bucket)为单位,放在JSON数组中返回,这些数据是没有排序的,今天来学习如何给这些数据进行排序

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos

本篇概览

  • 本文是《Elasticsearch聚合学习》系列的第四篇,在前面的实战中,聚合的结果以桶(bucket)为单位,放在JSON数组中返回,这些数据是没有排序的,今天来学习如何给这些数据进行排序;

系列文章列表

  1. 《Elasticsearch聚合学习之一:基本操作》
  2. 《Elasticsearch聚合学习之二:区间聚合》
  3. 《Elasticsearch聚合学习之三:范围限定》;
  4. 《Elasticsearch聚合学习之四:结果排序》

环境信息

  • 以下是本次实战的环境信息,请确保您的Elasticsearch可以正常运行:
  1. 操作系统:Ubuntu 18.04.2 LTS
  2. JDK:1.8.0_191
  3. Elasticsearch:6.7.1
  4. Kibana:6.7.1
  • 实战用的数据依然是一些汽车销售的记录,在第一章有详细的导入步骤,请参考操作,导入后您的es中的数据如下图:

在这里插入图片描述

  • 接下来一起实战聚合排序吧;

默认排序

  • 之前文章中的聚合查询,我们都没有做排序设置,此时es会用每个桶的doc_count字段做降序,下图是个terms桶聚合的示例,可见返回了三个bucket对象,是按照doc_count字段降序排列的:

在这里插入图片描述

内置排序

  • 除了自定义排序,es自身也内置了两种排序参数,可以直接拿来使用:
  • _count:这个参数对应的就是doc_count,以下请求的排序效果和默认的排序效果是一致的:
GET /cars/transactions/_search
{
  "size":0,
  "aggs":{
   "popular_colors":{
     "terms": {
       "field": "color",
       "order": {             ---表示要对聚合结果做排序
         "_count": "desc"     ---排序字段是doc_count,顺序是降序
       }
     }
   } 
  }
}
  • _key:在区间聚合的时候(histogram或者date_histogram),可以根据桶的key做排序:
GET /cars/transactions/_search
{
  "size": 0,
  "aggs": {
    "price": {
      "histogram": {           ---区间聚合
        "field": "price",      ---取price字段的值
        "interval": 20000,     ---每个区间的大小是20000
        "order": {             ---表示要对聚合结果做排序
          "_key": "desc"       ---排序字段是桶的key值,这里是每个区间的起始值,顺序是降序
        }
      }
    }
  }
}
  • 返回结果如下,已经按照key的大小从大到小排序:
  ......
  "aggregations" : {
    "price" : {
      "buckets" : [
        {
          "key" : 80000.0,
          "doc_count" : 1
        },
        {
          "key" : 60000.0,
          "doc_count" : 0
        },
        {
          "key" : 40000.0,
          "doc_count" : 0
        },
        {
          "key" : 20000.0,
          "doc_count" : 4
        },
        {
          "key" : 0.0,
          "doc_count" : 3
        }
      ]
    }
  }
}

在这里插入图片描述

  • 但是在实际操作中发现,6.7.1版本中,除了histogram 和 date_histogram,terms桶也可以用_key排序,如下图,是按照key的字母降序:

在这里插入图片描述

  • desc改为asc之后返回如下图,变成了按照key的首字母升序排序:

在这里插入图片描述

在这里插入图片描述

  • 也许是"手贱"的缘故,我还是用_term试了下,可以返回结果,但是会建议用_key替代_term,如下图:

在这里插入图片描述

按照metrics排序(metrics结果只有一个值)

  • 常见的metrics有累加和(sum)、最大值(max)、最小值(min)、平均值(avg),这些metrics的特点是处理结果只有一个值,我们可以按照这个结果来排序,例如计算每个汽车品牌的销售额,再按照销售额排序:
GET /cars/transactions/_search
{
  "size": 0,
  "aggs": {
    "sales_rank": {
      "terms": {               ---桶类型是terms
        "field": "make",       ---按照make字段聚合
        "order": {             ---要求排序
          "sales": "desc"      ---排序字段是sales
        }
      },
      "aggs": {
        "sales": {            ---metrics处理后的结果保存在名为sales的字段中,排序已经指定了该字段
          "sum": {            ---桶内的metrics处理,类型是累加
            "field": "price"  ---将price字段的值累加
          }
        }
      }
    }
  }
}
  • 下面是聚合结果,可见已按照每个品牌的销售额大小做了降序的排序:
......
  "aggregations" : {                          ---聚合结果
    "sales_rank" : {                          ---桶名称
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [                           ---这个JSON数组内是按照品牌聚合而成的所有桶
        {
          "key" : "bmw",                      ---品牌为bmw的桶
          "doc_count" : 1,                    ---文档数量为1
          "sales" : {                         ---metrics处理结果
            "value" : 80000.0                 ---品牌为bmw的汽车销售总额是80000
          }
        },
        {
          "key" : "ford",
          "doc_count" : 2,
          "sales" : {
            "value" : 55000.0
          }
        },
        {
          "key" : "honda",
          "doc_count" : 3,
          "sales" : {
            "value" : 50000.0
          }
        },
        {
          "key" : "toyota",
          "doc_count" : 2,
          "sales" : {
            "value" : 27000.0
          }
        }
      ]
    }
  }
}

按照metrics排序(metrics结果有多个值)

  • 和sum、max这些只有一个结果的metrics不同,extended_stats的结果包含了数量、最大值、最小值、平均值、累加和等多种处理,此时必须要指定用其中的哪一项(否则会返回错误:Invalid aggregation order path [xxxx]. When ordering on a multi-value metrics aggregation a metric name must be specified):
GET /cars/transactions/_search
{
  "size": 0,
  "aggs": {
    "sales_rank": {
      "terms": {                 ---桶类型是terms
        "field": "make",         ---按照make字段聚合
        "order": {               ---要求排序
          "stat.avg": "asc"      ---排序字段是metrics结果的一个子项(平均值),升序
        }
      },
      "aggs": {
        "stat": {                ---metrics处理后的结果保存在名为stat的字段中,排序已经指定了该字段的agv子项(平均值)
          "extended_stats": {    ---桶内的metrics处理,类型是计算数量、最大值、最小值、平均值等多个指标项
            "field": "price"     ---将price字段的值拿来做metrics处理
          }
        }
      }
    }
  }
}
  • 返回结果如下,可见已经按照metrics结果的avg子项做了升序排序:
......
"aggregations" : {
    "sales_rank" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "toyota",
          "doc_count" : 2,
          "stat" : {
            "count" : 2,
            "min" : 12000.0,
            "max" : 15000.0,
            "avg" : 13500.0,               ---排序字段
            "sum" : 27000.0,
            "sum_of_squares" : 3.69E8,
            "variance" : 2250000.0,
            "std_deviation" : 1500.0,
            "std_deviation_bounds" : {
              "upper" : 16500.0,
              "lower" : 10500.0
            }
          }
        },
        {
          "key" : "honda",
          "doc_count" : 3,
          "stat" : {
            "count" : 3,
            "min" : 10000.0,
            "max" : 20000.0,
            "avg" : 16666.666666666668,    ---排序字段
            "sum" : 50000.0,
            "sum_of_squares" : 9.0E8,
            "variance" : 2.222222222222221E7,
            "std_deviation" : 4714.045207910315,
            "std_deviation_bounds" : {
              "upper" : 26094.757082487296,
              "lower" : 7238.5762508460375
            }
          }
        },
        ......

嵌套桶排序

  • 在聚合查询中,经常对聚合的数据再次做聚合处理,例如统计每个汽车品牌下的每种颜色汽车的销售额,这时候DSL中就有了多层aggs对象的嵌套,这就是嵌套桶(此名称来自《Elasticsearch 权威指南》),如下图所示:

在这里插入图片描述

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
自然语言处理 Java 网络架构
elasticsearch学习三:elasticsearch-ik分词器的自定义配置 分词内容
这篇文章是关于如何自定义Elasticsearch的ik分词器配置以满足特定的中文分词需求。
158 0
elasticsearch学习三:elasticsearch-ik分词器的自定义配置 分词内容
|
4月前
|
SQL JSON 大数据
ElasticSearch的简单介绍与使用【进阶检索】 实时搜索 | 分布式搜索 | 全文搜索 | 大数据处理 | 搜索过滤 | 搜索排序
这篇文章是Elasticsearch的进阶使用指南,涵盖了Search API的两种检索方式、Query DSL的基本语法和多种查询示例,包括全文检索、短语匹配、多字段匹配、复合查询、结果过滤、聚合操作以及Mapping的概念和操作,还讨论了Elasticsearch 7.x和8.x版本中type概念的变更和数据迁移的方法。
ElasticSearch的简单介绍与使用【进阶检索】 实时搜索 | 分布式搜索 | 全文搜索 | 大数据处理 | 搜索过滤 | 搜索排序
|
1月前
|
存储 SQL 监控
|
2月前
|
JSON Java 网络架构
elasticsearch学习四:使用springboot整合 rest 进行搭建elasticsearch服务
这篇文章介绍了如何使用Spring Boot整合REST方式来搭建和操作Elasticsearch服务。
150 4
elasticsearch学习四:使用springboot整合 rest 进行搭建elasticsearch服务
|
2月前
|
自然语言处理 搜索推荐 关系型数据库
elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)
这篇文章是关于Elasticsearch全文搜索引擎的学习指南,涵盖了基本概念、命令风格、索引操作、分词器使用,以及数据的增加、修改、删除和查询等操作。
37 0
elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)
|
2月前
|
Web App开发 JavaScript Java
elasticsearch学习五:springboot整合 rest 操作elasticsearch的 实际案例操作,编写搜索的前后端,爬取京东数据到elasticsearch中。
这篇文章是关于如何使用Spring Boot整合Elasticsearch,并通过REST客户端操作Elasticsearch,实现一个简单的搜索前后端,以及如何爬取京东数据到Elasticsearch的案例教程。
227 0
elasticsearch学习五:springboot整合 rest 操作elasticsearch的 实际案例操作,编写搜索的前后端,爬取京东数据到elasticsearch中。
|
2月前
|
自然语言处理 Java Maven
elasticsearch学习二:使用springboot整合TransportClient 进行搭建elasticsearch服务
这篇博客介绍了如何使用Spring Boot整合TransportClient搭建Elasticsearch服务,包括项目创建、Maven依赖、业务代码和测试示例。
134 0
elasticsearch学习二:使用springboot整合TransportClient 进行搭建elasticsearch服务
|
2月前
|
存储 JSON Java
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
这篇文章是关于Elasticsearch的学习指南,包括了解Elasticsearch、版本对应、安装运行Elasticsearch和Kibana、安装head插件和elasticsearch-ik分词器的步骤。
228 0
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
|
3月前
|
存储 自然语言处理 关系型数据库
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
聚合、补全、RabbitMQ消息同步、集群、脑裂问题、集群分布式存储、黑马旅游实现过滤和搜索补全功能
|
4月前
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
159 1