文章目录

  • 1. 数据准备
  • 2. 过滤和聚合
    • 2.1 过滤
    • 2.2 过滤桶
  • 3. 多桶排序
    • 3.1 内置排序
    • 3.2 按度量排序
  • 4. 近似聚合

1. 数据准备

1、创建索引映射mapping :

PUT /cars
{"mappings": {"properties": {"price":{"type": "integer"},"color":{"type": "keyword"},"make":{"type": "keyword"},"sold":{"type": "date"}}}
}

2、索引文档:

POST /cars/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }

2. 过滤和聚合

2.1 过滤

如果我们想找到售价在 $10,000 美元之上的所有汽车同时也为这些车计算平均售价, 可以简单地使用一个 constant_score 查询和 filter 约束:

GET /cars/_search
{"size": 0,"query": {"constant_score": {"filter": {"range": {"price": {"gte": 2000}}}}},"aggs": {"avg_agg": {"avg": {"field": "price"}}}
}

从根本上讲,使用 non-scoring 查询和使用 match 查询没有任何区别。查询(包括了一个过滤器)返回一组文档的子集,聚合正是操作这些文档。使用 filtering query 会忽略评分,并有可能会缓存结果数据等等。

{"aggregations" : {"avg_agg" : {"value" : 26500.0}}
}

2.2 过滤桶

但是如果我们只想对聚合结果过滤怎么办? 假设我们正在为汽车经销商创建一个搜索页面, 我们希望显示用户搜索的结果,但是我们同时也想在页面上提供更丰富的信息,包括(与搜索匹配的)上个月度汽车的平均售价。

这里我们无法简单的做范围限定,因为有两个不同的条件。搜索结果必须是 ford ,但是聚合结果必须满足 ford AND sold > now - 1M

为了解决这个问题,我们可以用一种特殊的桶,叫做 filter 。 我们可以指定一个过滤桶,当文档满足过滤桶的条件时,我们将其加入到桶内。

GET /cars/_search
{"size": 0,"query": {"match": {"make": "ford"}},"aggs": {"recent_sales": {"filter": {    // 使用过滤桶在查询范围基础上应用过滤器 "range": {"sold": {"from": "now-1M"}}},"aggs": {      // avg度量只会对ford和上个月售出的文档计算平均售价"avg_price": {"avg": {       "field": "price"}}}}}
}

3. 多桶排序

多值桶( termshistogramdate_histogram )动态生成很多桶。 Elasticsearch 是如何决定这些桶展示给用户的顺序呢?

默认的,桶会根据 doc_count 降序排列。这是一个好的默认行为,因为通常我们想要找到文档中与查询条件相关的最大值:售价、人口数量、频率。但有些时候我们希望能修改这个顺序,不同的桶有着不同的处理方式。

3.1 内置排序

这些排序模式是桶固有的能力:它们操作桶生成的数据 ,比如 doc_count 。 它们共享相同的语法,但是根据使用桶的不同会有些细微差别。

让我们做一个 terms 聚合但是按 doc_count 值的升序排序:

GET /cars/_search
{"size": 0,"aggs": {"group_by_agg": {"terms": {"field": "color","order": {"_count": "asc"}}}}
}

我们为聚合引入了一个 order 对象, 它允许我们可以根据以下几个值中的一个值进行排序:

  • _count:按文档数排序。对 termshistogramdate_histogram 有效。
  • _term:按词项的字符串值的字母顺序排序。只在 terms 内使用。
  • _key:按每个桶的键值数值排序。 只在 histogramdate_histogram 内使用。
{"aggregations" : {"group_by_agg" : {"doc_count_error_upper_bound" : 0,"sum_other_doc_count" : 0,"buckets" : [{"key" : "blue","doc_count" : 2},{"key" : "green","doc_count" : 2},{"key" : "red","doc_count" : 4}]}}
}

3.2 按度量排序

有时,我们会想基于度量计算的结果值进行排序。我们可能想按照汽车颜色创建一个销售条状图表,但按照汽车平均售价的升序进行排序。我们可以增加一个度量,再指定 order 参数引用这个度量即可:

GET /cars/_search
{"size": 0,"aggs": {"group_by_agg": {"terms": {"field": "color","order": {"avg_price": "asc"  // 桶按照计算平均值的升序排序 }},"aggs": {"avg_price": {"avg": {"field": "price"}}}}}
}
{"took" : 7,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 8,"relation" : "eq"},"max_score" : null,"hits" : [ ]},"aggregations" : {"group_by_agg" : {"doc_count_error_upper_bound" : 0,"sum_other_doc_count" : 0,"buckets" : [{"key" : "blue","doc_count" : 2,"avg_price" : {"value" : 20000.0}},{"key" : "green","doc_count" : 2,"avg_price" : {"value" : 21000.0}},{"key" : "red","doc_count" : 4,"avg_price" : {"value" : 32500.0}}]}}
}

4. 近似聚合

如果所有的数据都在一台机器上,那么也就不需要像 Elasticsearch 这样的分布式软件了。不过一旦我们开始分布式存储数据,就需要小心地选择算法。

有些算法可以分布执行,到目前为止讨论过的所有聚合都是单次请求获得精确结果的。这些类型的算法通常被认为是高度并行的,因为它们无须任何额外代价,就能在多台机器上并行执行。 复杂的操作则需要在算法的性能和内存使用上做出权衡。对于这个问题,我们有个三角因子模型:大数据、精确性和实时性。我们需要选择其中两项:

  • 精确 + 实时:数据可以存入单台机器的内存之中,我们可以随心所欲,使用任何想用的算法。结果会 100% 精确,响应会相对快速。
  • 大数据 + 精确:传统的 Hadoop。可以处理 PB 级的数据并且为我们提供精确的答案,但它可能需要几周的时间才能为我们提供这个答案。
  • 大数据 + 实时:近似算法为我们提供准确但不精确的结果。

Elasticsearch 目前支持两种近似算法( cardinalitypercentiles )。 它们会提供准确但不是 100% 精确的结果。 以牺牲一点小小的估算错误为代价,这些算法可以为我们换来高速的执行效率和极小的内存消耗。

Elasticsearch 提供的首个近似聚合是 cardinality 度量。 它提供一个字段的基数,即该字段的 distinct 或者 unique 值的数目。 你可能会对 SQL 形式比较熟悉:

SELECT COUNT(DISTINCT color) FROM cars

去重是一个很常见的操作,可以回答很多基本的业务问题:

  • 网站独立访客是多少?
  • 卖了多少种汽车?
  • 每月有多少独立用户购买了商品?

我们可以用 cardinality 度量确定经销商销售汽车颜色的数量:

GET /cars/_search
{"size": 0,"aggs": {"distinct_color": {"cardinality": {"field": "color"}}}
}
{"aggregations" : {"distinct_color" : {"value" : 3}}
}

可以让我们的例子变得更有用:每月有多少颜色的车被售出?为了得到这个度量,我们只需要将一个 cardinality 度量嵌入一个 date_histogram

GET /cars/_search
{"size": 0,"aggs": {"month_agg": {"date_histogram": {"field": "sold","interval": "month","min_doc_count": 1},"aggs": {"color_agg": {"cardinality": {"field": "color"}}}}}
}
{"aggregations" : {"month_agg" : {"buckets" : [{"key_as_string" : "2014-01-01T00:00:00.000Z","key" : 1388534400000,"doc_count" : 1,"color_agg" : {"value" : 1}},{"key_as_string" : "2014-02-01T00:00:00.000Z","key" : 1391212800000,"doc_count" : 1,"color_agg" : {"value" : 1}},{"key_as_string" : "2014-05-01T00:00:00.000Z","key" : 1398902400000,"doc_count" : 1,"color_agg" : {"value" : 1}},{"key_as_string" : "2014-07-01T00:00:00.000Z","key" : 1404172800000,"doc_count" : 1,"color_agg" : {"value" : 1}},{"key_as_string" : "2014-08-01T00:00:00.000Z","key" : 1406851200000,"doc_count" : 1,"color_agg" : {"value" : 1}},{"key_as_string" : "2014-10-01T00:00:00.000Z","key" : 1412121600000,"doc_count" : 1,"color_agg" : {"value" : 1}},{"key_as_string" : "2014-11-01T00:00:00.000Z","key" : 1414800000000,"doc_count" : 2,"color_agg" : {"value" : 1}}]}}
}

深耕ElasticSearch - 过滤和聚合/多桶排序相关推荐

  1. Elasticsearch过滤与聚合的先后顺序java实现

    一.Elasticsearch的聚合 ES的聚合相当于关系型数据库里面的group by,例如查找在性别字段男女人数的多少并且按照人数的多少进行排序,在使用mysql的时候,可以使用如下的句子 sel ...

  2. es 时间过滤java,Elasticsearch过滤与聚合的先后顺序java实现

    一.Elasticsearch的聚合 ES的聚合相当于关系型数据库里面的group by,例如查找在性别字段男女人数的多少并且按照人数的多少进行排序,在使用MySQL的时候,可以使用如下的句子 sel ...

  3. [Elasticsearch] 过滤查询以及聚合(Filtering Queries and Aggregations)

    原文地址为: [Elasticsearch] 过滤查询以及聚合(Filtering Queries and Aggregations) 本章翻译自Elasticsearch官方指南的Filtering ...

  4. Elasticsearch查询和聚合基本语法

    1.概述 Elasticsearch主要的查询语法包括URI查询和body查询,URI比较轻便快速,而body查询作为一种json的格式化查询,可以有许多限制条件.本文主要介绍结构化查询的query, ...

  5. 七.全文检索ElasticSearch经典入门-聚合查询

    前言 今天我们讲ES的高亮和聚合查询,聚合功能是ES很重要的功能,它基于查询条件来对数据进行分桶和计算.它提供了类似于关系型数据库的SUM,COUNT, AVG , Group By 等功能.聚合也可 ...

  6. java操作es聚合操作并显示其他字段_深入浅析Elasticsearch中的聚合操作

    如果写过Elasticsearch的聚合操作DSL,都知道它非常的繁琐,很简单的业务就导致异常复杂的json.因为它的聚合操作是嵌套的,一个聚合的输出可以是另一个聚合的输入,并且聚合还支持pipeli ...

  7. ElasticSearch java API - 聚合查询-聚合多字段聚合demo

    以球员信息为例,player索引的player type包含5个字段,姓名,年龄,薪水,球队,场上位置. index的mapping为: "mappings": {"pl ...

  8. javascript算法排序之桶排序

    ​ ​ 活动地址:CSDN21天学习挑战赛 前言 经典的排序算法,很多人都听过,很多人也许用过,但是也有很多人,听过没见过.为什么呢?现在我们有了越来越多的框架.依赖包,我们将能用到排序的实际场景,作 ...

  9. python 实现桶排序

    前言 桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里.每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序).桶排序是鸽 ...

最新文章

  1. TensorFlow单层感知机实现
  2. python3 字典 dict 常见用法总结(判断key是否存在)
  3. 最新的ndkr20编译c_史上最优雅的NDK加载pass方案
  4. 需求评审五个维度框架分析及其带来的启示-5-结束语
  5. 看奥运之二:现场看男子体操团体决赛
  6. javaScript中const,var,let区别与用法详解
  7. umi config.js整体defineConfig配置
  8. 初识编码 gbk unicode utf-8
  9. VMware网络设置
  10. Android studio 突然 无法解析符号
  11. 阿里巴巴编码规范考试答案
  12. Catia二次开发:数组,局部变量等,msgbox,背景颜色,enable属性,图片模块,vb的common dialog控件,键盘鼠标事件,text操作
  13. Win7 64位系统不能使用农业银行网银
  14. 如何使用微信公众号做营销
  15. office软件的发展前景_2020年中国远程办公软件行业市场现状及发展前景分析
  16. 【Marvelous Designer 1】初学MD
  17. rapidio学习使用过程摘抄
  18. 行政区划编码映射关系-数据处理
  19. Google Earth Engine(GEE)——Python Landsat5/7/8合并、链接和属性统计(NBR案例分析)
  20. 我的电磁学讲义10:磁感应强度 毕奥-萨伐尔定律

热门文章

  1. 如何给图片更改格式?jpg转webp怎么操作
  2. java 动物声音模拟器_动物声音模拟器软件
  3. STM32开发项目:STM32F407的BootLoader程序
  4. Partial Dependence and Individual Conditional Expectation plots
  5. 深度学习论文精读(4):MobileNetV2
  6. 西行漫记(4):周末
  7. spring security oauth2 基于 RBAC 的自定义认证
  8. Vivado 下单端口RAM的配置使用
  9. windows黑窗口启动jar包常用命令
  10. 【JAVA程序设计】(C00101)基于Servlet的在线鞋店销售管理系统