把 Elasticsearch 当数据库使:聚合后排序

使用 https://github.com/taowen/es-monitor 可以用 SQL 进行 elasticsearch 的查询。有的时候分桶聚合之后会产生很多的桶,我们只对其中部分的桶关心。最简单的办法就是排序之后然后取前几位的结果。

ORDER BY _term

SQL

$ cat << EOF | ./es_query.py http://127.0.0.1:9200
SELECT ipo_year, COUNT(*) FROM symbol GROUP BY ipo_year ORDER BY ipo_year LIMIT 2
EOF
{"COUNT(*)": 4, "ipo_year": 1972}
{"COUNT(*)": 1, "ipo_year": 1973}

Elasticsearch

{
  "aggs": {
    "ipo_year": {
      "terms": {
        "field": "ipo_year",
        "order": [
          {
            "_term": "asc"
          }
        ],
        "size": 2
      },
      "aggs": {}
    }
  },
  "size": 0
}

因为 ipo_year 是 GROUP BY 的字段,所以按这个排序用_term指代。

{
  "hits": {
    "hits": [],
    "total": 6714,
    "max_score": 0.0
  },
  "_shards": {
    "successful": 1,
    "failed": 0,
    "total": 1
  },
  "took": 3,
  "aggregations": {
    "ipo_year": {
      "buckets": [
        {
          "key": 1972,
          "doc_count": 4
        },
        {
          "key": 1973,
          "doc_count": 1
        }
      ],
      "sum_other_doc_count": 2893,
      "doc_count_error_upper_bound": 0
    }
  },
  "timed_out": false
}

ORDER BY _count

SQL

$ cat << EOF | ./es_query.py http://127.0.0.1:9200
SELECT ipo_year, COUNT(*) AS ipo_count FROM symbol GROUP BY ipo_year ORDER BY ipo_count LIMIT 2
EOF
{"ipo_count": 1, "ipo_year": 1973}
{"ipo_count": 2, "ipo_year": 1980}

Elasticsearch

{
  "aggs": {
    "ipo_year": {
      "terms": {
        "field": "ipo_year",
        "order": [
          {
            "_count": "asc"
          }
        ],
        "size": 2
      },
      "aggs": {}
    }
  },
  "size": 0
}
{
  "hits": {
    "hits": [],
    "total": 6714,
    "max_score": 0.0
  },
  "_shards": {
    "successful": 1,
    "failed": 0,
    "total": 1
  },
  "took": 2,
  "aggregations": {
    "ipo_year": {
      "buckets": [
        {
          "key": 1973,
          "doc_count": 1
        },
        {
          "key": 1980,
          "doc_count": 2
        }
      ],
      "sum_other_doc_count": 2895,
      "doc_count_error_upper_bound": -1
    }
  },
  "timed_out": false
}

ORDER BY 指标

SQL

$ cat << EOF | ./es_query.py http://127.0.0.1:9200
    SELECT ipo_year, MAX(market_cap) AS max_market_cap FROM symbol
    GROUP BY ipo_year ORDER BY max_market_cap LIMIT 2
EOF
{"max_market_cap": 826830000.0, "ipo_year": 1982}
{"max_market_cap": 847180000.0, "ipo_year": 2016}

Elasticsearch

{
  "aggs": {
    "ipo_year": {
      "terms": {
        "field": "ipo_year",
        "order": [
          {
            "max_market_cap": "asc"
          }
        ],
        "size": 2
      },
      "aggs": {
        "max_market_cap": {
          "max": {
            "field": "market_cap"
          }
        }
      }
    }
  },
  "size": 0
}
{
  "hits": {
    "hits": [],
    "total": 6714,
    "max_score": 0.0
  },
  "_shards": {
    "successful": 1,
    "failed": 0,
    "total": 1
  },
  "took": 20,
  "aggregations": {
    "ipo_year": {
      "buckets": [
        {
          "max_market_cap": {
            "value": 826830000.0
          },
          "key": 1982,
          "doc_count": 4
        },
        {
          "max_market_cap": {
            "value": 847180000.0
          },
          "key": 2016,
          "doc_count": 6
        }
      ],
      "sum_other_doc_count": 2888,
      "doc_count_error_upper_bound": -1
    }
  },
  "timed_out": false
}

HISTOGRAM 和 ORDER BY

除了 terms aggregation,其他 aggregation 也支持 order by 但是并不完善。比如 histogram aggregation 支持 sort 但是并不支持 size (也就是可以ORDER BY 但是不能 LIMIT)。官方有计划增加一个通用的支持 LIMIT 的方式,不过还没有实现:https://github.com/elastic/elasticsearch/issues/14928

SQL

$ cat << EOF | ./es_query.py http://127.0.0.1:9200
    SELECT ipo_year_range, MAX(market_cap) AS max_market_cap FROM symbol
    GROUP BY histogram(ipo_year, 10) AS ipo_year_range ORDER BY ipo_year_range
EOF
{"ipo_year_range": 1970, "max_market_cap": 18370000000.0}
{"ipo_year_range": 1980, "max_market_cap": 522690000000.0}
{"ipo_year_range": 1990, "max_market_cap": 230940000000.0}
{"ipo_year_range": 2000, "max_market_cap": 470490000000.0}
{"ipo_year_range": 2010, "max_market_cap": 287470000000.0}

Elasticsearch

{
  "aggs": {
    "ipo_year_range": {
      "aggs": {
        "max_market_cap": {
          "max": {
            "field": "market_cap"
          }
        }
      },
      "histogram": {
        "field": "ipo_year",
        "interval": 10,
        "order": {
          "_key": "asc"
        }
      }
    }
  },
  "size": 0
}
{
  "hits": {
    "hits": [],
    "total": 6714,
    "max_score": 0.0
  },
  "_shards": {
    "successful": 1,
    "failed": 0,
    "total": 1
  },
  "took": 2,
  "aggregations": {
    "ipo_year_range": {
      "buckets": [
        {
          "max_market_cap": {
            "value": 18370000000.0
          },
          "key": 1970,
          "doc_count": 5
        },
        {
          "max_market_cap": {
            "value": 522690000000.0
          },
          "key": 1980,
          "doc_count": 155
        },
        {
          "max_market_cap": {
            "value": 230940000000.0
          },
          "key": 1990,
          "doc_count": 598
        },
        {
          "max_market_cap": {
            "value": 470490000000.0
          },
          "key": 2000,
          "doc_count": 745
        },
        {
          "max_market_cap": {
            "value": 287470000000.0
          },
          "key": 2010,
          "doc_count": 1395
        }
      ]
    }
  },
  "timed_out": false
}
时间: 2024-10-29 02:47:00

把 Elasticsearch 当数据库使:聚合后排序的相关文章

数据库表分组后按时间排序,取每个分组中最近的一条记录

数据库表分组后按时间排序,取每个分组中最近的一条记录.在网上找了好几个,都不行,最终找到了解决办法,Oracle亲测可以. with m as (select id,max(times) c from test_max group by id)select n.id,n.duowei from test_max n join m on m.id=n.id and m.c=n.times 第一次在博客园写知识,愿意和大家分享.

Python全栈 MongoDB 数据库(聚合、二进制、GridFS、pymongo模块)

断网了2天  今天补上 聚合操作: 对文档的信息进行整理统计的操作 返回:统计后的文档集合 db.collection.aggregate() 功能:聚合函数,完成聚合操作 参数:聚合条件,配合聚合操作符使用 返回:聚合后的结果 常用聚合操作符: 1.$group  分组聚合   要配合具体的统计操作符获取结果 $sum  求和 db.class1.aggregate({$group:{_id:'$gender',num:{$sum:1}}}) 分组   按照gender值统计 统计结果,求和每

MySQL数据库的自动备份与数据库被破坏后的恢复(3)

[2] 当数据库被修改后的恢复方法 数据库被修改,可能存在着多方面的原因,被入侵.以及相应程序存在Bug等等,这里不作详细介绍.这里将只介绍在数据库被修改后,如果恢复到被修改前状态的方法. 具体和上面所述的“数据库被删除后的恢复方法”相类似.这里,测试用数据库接着使用刚刚在前面用过的test.这里为了使刚刚接触数据库的朋友不至于理解混乱,我们再次登录到MySQL服务器上确认一下刚刚建立的测试用的数据库test的相关信息. [[email protected] ~]# mysql -u root

MySQL数据库的自动备份与数据库被破坏后的恢复1

一.前言: 当数据库服务器建立好以后,我们首先要做的不是考虑要在这个支持数据库的服务器运行哪些受MySQL提携的程序,而是当数据库遭到破坏后,怎样安然恢复到最后一次正常的状态,使得数据的损失达到最小. 或者说,仅仅是数据库服务器的建立,只能说明它能做些什么,并不代表它能稳定的做些什么.灾难恢复的效率及全面性,也是系统的稳定性的一个准因素,尤其对于一个服务器系统. 这一节,介绍数据库自动备份以及数据库被破坏后的恢复的方法.在这里,我们使用mysqlhotcopy,并且定义一段Shell脚本来实现数

[SQL] SQL 基础知识梳理(三)- 聚合和排序

SQL 基础知识梳理(三)- 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 目录 一.对表进行聚合查询 1.聚合函数 (1)5 个常用函数: ①COUNT:计算表中的记录(行)数. ②SUM:计算表中数值列的数据合计值. ③AVG:计算表中数值列的数据平均值. ④MAX:求出表中任意列中数据的最大值. ⑤MIN:求出表中任意列中数据的最小值. (2)聚合:将多行汇总成一行. 图1-1 Shohin 表 2.计算

解决UNION ALL合并两个结果集后排序的问题

日常开发中,如果实用UNION ALL合并两个已经排好序的结果集的时候,需求是第二个结果集数据排在第一个结果集数据下面,单纯的实用order by是无效的,因为order by的优先级比UNION ALL低. 例如: select one.*  from (select t1.* from table1 t1 where 1=1 and t1.day >3 order by t1.create_date desc)  one UNION ALL select two.*  from (selec

3 聚合与排序

3 聚合与排序 3-1 对表进行聚合查询 聚合函数 通过SQL对数据进行 操作或计算时需要使用函数. 计算表中全部数据行数时,可以使用COUNT函数. COUNT : 计算表中的记录数(行数). SUM : 计算表中数值列的数据合计值. AVG : 计算表中数值列的数据平均值. MAX :计算表中任意列中数据的最大值. MIN :计算表中任意列中数据的最小值. 如上所示,用于合计的函数称为聚合函数或者集合函数.本书中统称为聚合函数.所谓聚合,就是将多行汇总为一行. 函数这个词,与我们在学校课上学

MySQL数据库的自动备份与数据库被破坏后的恢复(2)

测试自动备份正常运转与否(备份恢复的方法) 这里,以通过实际操作的过程来介绍问题出现后的恢复方法. [1] 当数据库被删除后的恢复方法 首先建立一个测试用的数据库. [[email protected] ~]# mysql -u root -p ← 用root登录到MySQL服务器 Enter password: ← 输入MySQL的root用户密码 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL conne

Oracle 数据库 JOB 失败后的重试规律解密

由于官方文档上没有找到相关的说明,所以这里进行了如下测试,为了找到oracle数据库中 job 失败后重试时间的规律. 数据库版本:11.2.0.3 测试说明:这里创建了一个日志表以及一个运行时必定出错的procedure,用于job的运行.这里只要记录下每次job执行时视图user_jobs 中的 next_date就可以推断出job 执行失败后的重试规律. 为了测试job的重试规律我做了如下工作 日志表以及序列: create table job_exec_logs (id number ,