聚合

聚合

elasticsearach在聚合时为什么没有去除停用词

Elasticsearchrochy 回复了问题 • 3 人关注 • 1 个回复 • 86 次浏览 • 2018-11-12 23:31 • 来自相关话题

如何读取聚合之后的数据

Elasticsearchxuejl 回复了问题 • 3 人关注 • 4 个回复 • 189 次浏览 • 2018-10-31 10:17 • 来自相关话题

对子聚合结果进行统计

Kibanazqc0512 回复了问题 • 3 人关注 • 3 个回复 • 213 次浏览 • 2018-10-16 11:02 • 来自相关话题

ES1.7.5中对分词之后的字段进行聚合,如何设置字段属性是keyword

ElasticsearchesLitteBane 回复了问题 • 2 人关注 • 3 个回复 • 151 次浏览 • 2018-10-15 11:00 • 来自相关话题

如何理解es的百分位数聚合(Percentiles Aggregation)?

回复

Elasticsearchluohuanfeng 回复了问题 • 2 人关注 • 1 个回复 • 256 次浏览 • 2018-09-19 12:25 • 来自相关话题

如果是多个字段的聚合,那么tophits下再加子聚合吗?

ElasticsearchelasticStack 回复了问题 • 3 人关注 • 1 个回复 • 155 次浏览 • 2018-09-12 12:01 • 来自相关话题

es能在聚合结果中显示每个桶里文档内容吗?

Elasticsearchbsll 回复了问题 • 2 人关注 • 1 个回复 • 190 次浏览 • 2018-09-04 17:01 • 来自相关话题

嵌套模型的统计脚本怎么同时计算嵌套字段和父字段

回复

Elasticsearchyjp 发起了问题 • 1 人关注 • 0 个回复 • 205 次浏览 • 2018-08-07 17:03 • 来自相关话题

es的group by在多shard下是不精确的?

Elasticsearchzhangg7723 回复了问题 • 4 人关注 • 3 个回复 • 364 次浏览 • 2018-08-03 20:24 • 来自相关话题

搜索结果去重或者做聚合问题

Elasticsearchrochy 回复了问题 • 2 人关注 • 1 个回复 • 299 次浏览 • 2018-07-20 11:29 • 来自相关话题

如何对聚合得到的结果再次统计

Elasticsearchrochy 回复了问题 • 2 人关注 • 1 个回复 • 290 次浏览 • 2018-07-13 10:28 • 来自相关话题

es小的聚集查询在前端非正常压力后延迟忽然变高

Elasticsearchsterne vencel 回复了问题 • 2 人关注 • 2 个回复 • 3429 次浏览 • 2018-07-02 10:30 • 来自相关话题

es聚合统计的一个问题

回复

Elasticsearchamonxu 发起了问题 • 2 人关注 • 0 个回复 • 996 次浏览 • 2018-06-19 12:35 • 来自相关话题

假设存在user字段记录用户账号、time字段记录用户登陆时间,如何确定一个月内,哪些用户曾在凌晨两点至四点登陆过?

Elasticsearchliyh122 回复了问题 • 3 人关注 • 2 个回复 • 359 次浏览 • 2018-06-05 09:59 • 来自相关话题

聚合没有设置查询条件,报错是什么情况?

Elasticsearchlaoyang360 回复了问题 • 3 人关注 • 3 个回复 • 396 次浏览 • 2018-05-25 18:44 • 来自相关话题

条新动态, 点击查看
我知道了。
      "aggs": {
        "avg_rating": {
          "avg": {
            "script": &qu... 显示全部 »
我知道了。
      "aggs": {
        "avg_rating": {
          "avg": {
            "script": "_score"
          }
        }
      }
聚合部分这样写就可以了,如果script报
【scripts of type [inline], operation [aggs] and lang [groovy] are disabled】的错误
就在
就在配置文件elasticsearch.yml里

script.inline: on
script.indexed: on
script.engine.groovy.inline.aggs: on
script.engine.groovy.inline.update: on这几行配置加上然后重启els就可以了
 
我已经使用在了生产环境,是没有问题的。这个问题纠结了几天,终于找到方法了,跟帖在这里。
bsll

bsll 回答了问题 • 2016-11-16 17:14 • 2 个回复 不感兴趣

一个nested字段聚合父子字段

赞同来自:

写了一个demo,不过不知道你是不是这个意思。
DELETE /test_agg
PUT /test_agg
{
   "mappings": {
      "agg_type": {
          "... 显示全部 »
写了一个demo,不过不知道你是不是这个意思。
DELETE /test_agg
PUT /test_agg
{
   "mappings": {
      "agg_type": {
          "properties": {
          "all":{
              "type": "nested",
              "properties": {
                  "parent_id": {
                     "type": "integer"
                  },
                  "child_id": {
                     "type": "integer"
                  }
              }
          }
          }
      }
   }
}

POST /test_agg/agg_type/1
{
    "all":{
        "parent_id":1,
        "child_id":2
        
    }
}
POST /test_agg/agg_type/2
{
    "all":{
        "parent_id":1,
        "child_id":3
        
    }
}
POST /test_agg/agg_type/3
{
    "all":{
        "parent_id":2,
        "child_id":3
        
    }
}
POST /test_agg/_search
POST /test_agg/agg_type/_search
{
    "size": 0, 
   "aggs": {
      "category": {
         "aggs": {
            "term_list": {
               "terms": {
                  "field": "all.parent_id"
               },
               "aggs": {
                  "term_list": {
                     "terms": {
                        "field": "all.child_id"
                     }
                  }
               }
            }
         },
         "nested": {
            "path": "all"
         }
      }
   }
}
 
kennywu76

kennywu76 回答了问题 • 2017-06-28 11:16 • 4 个回复 不感兴趣

Elasticsearch聚合操作的时间复杂度是O(n)吗?

赞同来自:

terms聚合的时间复杂度不是一个简单的O能解释的,中间有好几个执行步骤,每个步骤的耗时也有多个决定因素。
 
最简单的单层terms聚合大致是下面这样一个执行步骤:
[list=1]
为要聚合的字段构造Global Ordinals。 (什么是Global... 显示全部 »
terms聚合的时间复杂度不是一个简单的O能解释的,中间有好几个执行步骤,每个步骤的耗时也有多个决定因素。
 
最简单的单层terms聚合大致是下面这样一个执行步骤:
[list=1]
为要聚合的字段构造Global Ordinals。 (什么是Global Ordinals参考 global-ordinals . ), 这个过程的速度不是单纯和文档数量有关系,更多的是取决于索引有多少个段文件,以及字段的不同唯一值的数量(cardinality)。  段文件的数量和磁盘IO能力决定了多快能将这些数据读入内存,而字段唯一值的多少决定了需要在内存里生成多少个分桶,唯一值越多,分桶占用的内存越高。
根据match查询的结果,也就是得到的文档ID集合,借助统计字段的doc values,拿到统计字段的值集合。
将统计字段的值集合映射到为global ordinals构建的分桶里。
统计各个分桶里的值个数.
根据聚合设置的size,返回top size的分桶数据。
[/list]
 
海量数据场景下,对Terms aggregation性能影响最大的还是对应字段的唯一值的多寡。 冷执行的情况下,由于需要读取各个segments的doc values,如果segments非常多,构造global ordinals可能耗时非常长。对于不再更新的索引,将其force merge成一个segment,可以免去global ordinals的构造过程,从而极大提速聚合速度。 对于一直在更新的索引,可以延长索引refresh周期,提高global ordinals缓存的有效期。 在查询聚合性能要求高于写入性能的场景下,也可以利用eager_global_ordinals来将构建时间移到索引阶段。
 
如果聚合的场景是从大量的数据中过滤出少量数据进行聚合(百万级),可以在执行参数里加入 execution_hint: map ,直接在结果集上用map的方式进行计算,对比默认的global ordinals的计算方式速度可能会高几倍到几十倍。
 
如果是多层聚合,则又要复杂得多,bucket构建过程分为depth first和breath first两种,建议仔细读一下相关文档,结合数据特性进行测试分析后,选用合适的执行方式。
 
总结来说对于terms aggregation,ES提供了多种执行方式,各种方式在内存使用方面,速度方面各有取舍。通常来说,默认的执行方式多数场景下都没有什么问题,只有一些比较极端的场景下,ES不会非常智能的自动选择最佳执行路径,需要使用者对数据和ES本身有一定熟悉程度,灵活选择。

elasticsearach在聚合时为什么没有去除停用词

回复

Elasticsearchrochy 回复了问题 • 3 人关注 • 1 个回复 • 86 次浏览 • 2018-11-12 23:31 • 来自相关话题

如何读取聚合之后的数据

回复

Elasticsearchxuejl 回复了问题 • 3 人关注 • 4 个回复 • 189 次浏览 • 2018-10-31 10:17 • 来自相关话题

对子聚合结果进行统计

回复

Kibanazqc0512 回复了问题 • 3 人关注 • 3 个回复 • 213 次浏览 • 2018-10-16 11:02 • 来自相关话题

ES1.7.5中对分词之后的字段进行聚合,如何设置字段属性是keyword

回复

ElasticsearchesLitteBane 回复了问题 • 2 人关注 • 3 个回复 • 151 次浏览 • 2018-10-15 11:00 • 来自相关话题

如何理解es的百分位数聚合(Percentiles Aggregation)?

回复

Elasticsearchluohuanfeng 回复了问题 • 2 人关注 • 1 个回复 • 256 次浏览 • 2018-09-19 12:25 • 来自相关话题

如果是多个字段的聚合,那么tophits下再加子聚合吗?

回复

ElasticsearchelasticStack 回复了问题 • 3 人关注 • 1 个回复 • 155 次浏览 • 2018-09-12 12:01 • 来自相关话题

es能在聚合结果中显示每个桶里文档内容吗?

回复

Elasticsearchbsll 回复了问题 • 2 人关注 • 1 个回复 • 190 次浏览 • 2018-09-04 17:01 • 来自相关话题

嵌套模型的统计脚本怎么同时计算嵌套字段和父字段

回复

Elasticsearchyjp 发起了问题 • 1 人关注 • 0 个回复 • 205 次浏览 • 2018-08-07 17:03 • 来自相关话题

es的group by在多shard下是不精确的?

回复

Elasticsearchzhangg7723 回复了问题 • 4 人关注 • 3 个回复 • 364 次浏览 • 2018-08-03 20:24 • 来自相关话题

搜索结果去重或者做聚合问题

回复

Elasticsearchrochy 回复了问题 • 2 人关注 • 1 个回复 • 299 次浏览 • 2018-07-20 11:29 • 来自相关话题

如何对聚合得到的结果再次统计

回复

Elasticsearchrochy 回复了问题 • 2 人关注 • 1 个回复 • 290 次浏览 • 2018-07-13 10:28 • 来自相关话题

es小的聚集查询在前端非正常压力后延迟忽然变高

回复

Elasticsearchsterne vencel 回复了问题 • 2 人关注 • 2 个回复 • 3429 次浏览 • 2018-07-02 10:30 • 来自相关话题

es聚合统计的一个问题

回复

Elasticsearchamonxu 发起了问题 • 2 人关注 • 0 个回复 • 996 次浏览 • 2018-06-19 12:35 • 来自相关话题

聚合没有设置查询条件,报错是什么情况?

回复

Elasticsearchlaoyang360 回复了问题 • 3 人关注 • 3 个回复 • 396 次浏览 • 2018-05-25 18:44 • 来自相关话题

ElasticSearch java API - 聚合查询

Elasticsearchcarlislelee 发表了文章 • 3 个评论 • 30091 次浏览 • 2016-09-20 17:16 • 来自相关话题

以球员信息为例,player索引的player type包含5个字段,姓名,年龄,薪水,球队,场上位置。 index的mapping为:
"mappings": {
	"player": {
		"properties": {
			"name": {
				"index": "not_analyzed",
				"type": "string"
			},
			"age": {
				"type": "integer"
			},
			"salary": {
				"type": "integer"
			},
			"team": {
				"index": "not_analyzed",
				"type": "string"
			},
			"position": {
				"index": "not_analyzed",
				"type": "string"
			}
		},
		"_all": {
			"enabled": false
		}
	}
}
索引中的全部数据:
微信截图_20160920171030.png
  首先,初始化Builder:
SearchRequestBuilder sbuilder = client.prepareSearch("player").setTypes("player");
接下来举例说明各种聚合操作的实现方法,因为在es的api中,多字段上的聚合操作需要用到子聚合(subAggregation),初学者可能找不到方法(网上资料比较少,笔者在这个问题上折腾了两天,最后度了源码才彻底搞清楚T_T),后边会特意说明多字段聚合的实现方法。另外,聚合后的排序也会单独说明。
  • group by/count
例如要计算每个球队的球员数,如果使用SQL语句,应表达如下:
select team, count(*) as player_count from player group by team;
ES的java api:
TermsBuilder teamAgg= AggregationBuilders.terms("player_count ").field("team");
sbuilder.addAggregation(teamAgg);
SearchResponse response = sbuilder.execute().actionGet();
 
  • group by多个field
例如要计算每个球队每个位置的球员数,如果使用SQL语句,应表达如下:
select team, position, count(*) as pos_count from player group by team, position;
ES的java api:
TermsBuilder teamAgg= AggregationBuilders.terms("player_count ").field("team");
TermsBuilder posAgg= AggregationBuilders.terms("pos_count").field("position");
sbuilder.addAggregation(teamAgg.subAggregation(posAgg));
SearchResponse response = sbuilder.execute().actionGet();
 
  • max/min/sum/avg
例如要计算每个球队年龄最大/最小/总/平均的球员年龄,如果使用SQL语句,应表达如下:
select team, max(age) as max_age from player group by team;
ES的java api:
TermsBuilder teamAgg= AggregationBuilders.terms("player_count ").field("team");
MaxBuilder ageAgg= AggregationBuilders.max("max_age").field("age");
sbuilder.addAggregation(teamAgg.subAggregation(ageAgg));
SearchResponse response = sbuilder.execute().actionGet();
  • 对多个field求max/min/sum/avg
例如要计算每个球队球员的平均年龄,同时又要计算总年薪,如果使用SQL语句,应表达如下:
select team, avg(age)as avg_age, sum(salary) as total_salary from player group by team;
ES的java api:
TermsBuilder teamAgg= AggregationBuilders.terms("team");
AvgBuilder ageAgg= AggregationBuilders.avg("avg_age").field("age");
SumBuilder salaryAgg= AggregationBuilders.avg("total_salary ").field("salary");
sbuilder.addAggregation(teamAgg.subAggregation(ageAgg).subAggregation(salaryAgg));
SearchResponse response = sbuilder.execute().actionGet();
 
  • 聚合后对Aggregation结果排序
例如要计算每个球队总年薪,并按照总年薪倒序排列,如果使用SQL语句,应表达如下:
select team, sum(salary) as total_salary from player group by team order by total_salary desc;
ES的java api:
TermsBuilder teamAgg= AggregationBuilders.terms("team").order(Order.aggregation("total_salary ", false);
SumBuilder salaryAgg= AggregationBuilders.avg("total_salary ").field("salary");
sbuilder.addAggregation(teamAgg.subAggregation(salaryAgg));
SearchResponse response = sbuilder.execute().actionGet();
需要特别注意的是,排序是在TermAggregation处执行的,Order.aggregation函数的第一个参数是aggregation的名字,第二个参数是boolean型,true表示正序,false表示倒序。 
  • Aggregation结果条数的问题
默认情况下,search执行后,仅返回10条聚合结果,如果想反悔更多的结果,需要在构建TermsBuilder 时指定size:
TermsBuilder teamAgg= AggregationBuilders.terms("team").size(15);
 
  • Aggregation结果的解析/输出
得到response后:
Map<String, Aggregation> aggMap = response.getAggregations().asMap();
StringTerms teamAgg= (StringTerms) aggMap.get("keywordAgg");
Iterator<Bucket> teamBucketIt = teamAgg.getBuckets().iterator();
while (teamBucketIt .hasNext()) {
Bucket buck = teamBucketIt .next();
//球队名
String team = buck.getKey();
//记录数
long count = buck.getDocCount();
//得到所有子聚合
Map subaggmap = buck.getAggregations().asMap();
//avg值获取方法
double avg_age= ((InternalAvg) subaggmap.get("avg_age")).getValue();
//sum值获取方法
double total_salary = ((InternalSum) subaggmap.get("total_salary")).getValue();
//...
//max/min以此类推
}
 
  • 总结
综上,聚合操作主要是调用了SearchRequestBuilder的addAggregation方法,通常是传入一个TermsBuilder,子聚合调用TermsBuilder的subAggregation方法,可以添加的子聚合有TermsBuilder、SumBuilder、AvgBuilder、MaxBuilder、MinBuilder等常见的聚合操作。   从实现上来讲,SearchRequestBuilder在内部保持了一个私有的 SearchSourceBuilder实例, SearchSourceBuilder内部包含一个List<AbstractAggregationBuilder>,每次调用addAggregation时会调用 SearchSourceBuilder实例,添加一个AggregationBuilder。 同样的,TermsBuilder也在内部保持了一个List<AbstractAggregationBuilder>,调用addAggregation方法(来自父类addAggregation)时会添加一个AggregationBuilder。有兴趣的读者也可以阅读源码的实现。   如果有什么问题,欢迎一起讨论,如果文中有什么错误,欢迎批评指正。   注:文中使用的Elastic Search API版本为2.3.2