ElasticSearch聚合操作详解

文章目录

  • 聚合操作
    • 聚合的分类
    • 测试数据
    • Metric Aggregation
    • Bucket Aggregation
      • 获取job的分类信息
      • 限定聚合范围
      • Range & Histogram聚合
      • 聚合嵌套
    • Pipeline Aggregation
    • 聚合的作用范围
    • 排序
    • ES聚合分析不精准原因分析
    • 聚合性能优化
      • 启用 eager global ordinals 提升高基数聚合性能
      • 插入数据时对索引进行预排序
      • 使用节点查询缓存
      • 使用分片请求缓存
      • 拆分聚合,使聚合并行化

聚合操作

聚合查询的语法结构与其他查询相似,通常包含以下部分:

  • 查询条件:指定需要聚合的文档,可以使用标准的 Elasticsearch 查询语法,如 term、match、range 等等。
  • 聚合函数:指定要执行的聚合操作,如 sum、avg、min、max、terms、date_histogram 等等。每个聚合命令都会生成一个聚合结果。
  • 聚合嵌套:聚合命令可以嵌套,以便更细粒度地分析数据。
GET <index_name>/_search
{"aggs": {"<aggs_name>": { #  聚合名称需要自己定义"<agg_type>": {		# 聚合种类,比如是桶聚合(terms)或者是指标聚合(avg、sum、min、max等)"field": "<field_name>"			#  field_name 字段名称或者叫域名。}}}
}

聚合操作一般都是操作的术语级别的字段,一般不会操作text类型的字段



聚合的分类

  • Metric Aggregation:—些数学运算,可以对文档字段进行统计分析,类比Mysql中的 min(), max(), sum() 操作。
GET /sys_user/_search
{"aggs": {"hs_avg_age": {"avg": {		# 这里还可以使用 max   min 等等"field": "age"}}}
}



  • Bucket Aggregation: 一些满足特定条件的文档的集合放置到一个桶里,每一个桶关联一个key,类比Mysql中的group by操作。

    # 使用terms关键字
    # 类似于关系型数据库的分组操作
    # 先分组 再求和
    GET /sys_user/_search
    {"aggs": {"hs_terms_age": {"terms": {  # 使用terms关键字"field": "age"}}}
    }
    

    在这里插入图片描述



  • Pipeline Aggregation:对其他的聚合结果进行二次聚合



测试数据

聚合操作一般都是操作术语级别的字段,比较少操作text类型的字段

DELETE /employees
#创建索引库
PUT /employees
{"mappings": {"properties": {"age":{"type": "integer"},"gender":{"type": "keyword"},"job":{"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 50}}},"name":{"type": "keyword"},"salary":{"type": "integer"}}}
}PUT /employees/_bulk
{ "index" : {  "_id" : "1" } }
{ "name" : "Emma","age":32,"job":"Product Manager","gender":"female","salary":35000 }
{ "index" : {  "_id" : "2" } }
{ "name" : "Underwood","age":41,"job":"Dev Manager","gender":"male","salary": 50000}
{ "index" : {  "_id" : "3" } }
{ "name" : "Tran","age":25,"job":"Web Designer","gender":"male","salary":18000 }
{ "index" : {  "_id" : "4" } }
{ "name" : "Rivera","age":26,"job":"Web Designer","gender":"female","salary": 22000}
{ "index" : {  "_id" : "5" } }
{ "name" : "Rose","age":25,"job":"QA","gender":"female","salary":18000 }
{ "index" : {  "_id" : "6" } }
{ "name" : "Lucy","age":31,"job":"QA","gender":"female","salary": 25000}
{ "index" : {  "_id" : "7" } }
{ "name" : "Byrd","age":27,"job":"QA","gender":"male","salary":20000 }
{ "index" : {  "_id" : "8" } }
{ "name" : "Foster","age":27,"job":"Java Programmer","gender":"male","salary": 20000}
{ "index" : {  "_id" : "9" } }
{ "name" : "Gregory","age":32,"job":"Java Programmer","gender":"male","salary":22000 }
{ "index" : {  "_id" : "10" } }
{ "name" : "Bryant","age":20,"job":"Java Programmer","gender":"male","salary": 9000}
{ "index" : {  "_id" : "11" } }
{ "name" : "Jenny","age":36,"job":"Java Programmer","gender":"female","salary":38000 }
{ "index" : {  "_id" : "12" } }
{ "name" : "Mcdonald","age":31,"job":"Java Programmer","gender":"male","salary": 32000}
{ "index" : {  "_id" : "13" } }
{ "name" : "Jonthna","age":30,"job":"Java Programmer","gender":"female","salary":30000 }
{ "index" : {  "_id" : "14" } }
{ "name" : "Marshall","age":32,"job":"Javascript Programmer","gender":"male","salary": 25000}
{ "index" : {  "_id" : "15" } }
{ "name" : "King","age":33,"job":"Java Programmer","gender":"male","salary":28000 }
{ "index" : {  "_id" : "16" } }
{ "name" : "Mccarthy","age":21,"job":"Javascript Programmer","gender":"male","salary": 16000}
{ "index" : {  "_id" : "17" } }
{ "name" : "Goodwin","age":25,"job":"Javascript Programmer","gender":"male","salary": 16000}
{ "index" : {  "_id" : "18" } }
{ "name" : "Catherine","age":29,"job":"Javascript Programmer","gender":"female","salary": 20000}
{ "index" : {  "_id" : "19" } }
{ "name" : "Boone","age":30,"job":"DBA","gender":"male","salary": 30000}
{ "index" : {  "_id" : "20" } }
{ "name" : "Kathy","age":29,"job":"DBA","gender":"female","salary": 20000}



Metric Aggregation

—些数学运算,可以对文档字段进行统计分析,类比Mysql中的 min(), max(), sum() 操作。

  • 单值分析︰只输出一个分析结果

    • min, max, avg, sum
    • Cardinality(类似distinct Count)
  • 多值分析:输出多个分析结果

    • stats(统计), extended stats

    • percentile (百分位), percentile rank

    • top hits(排在前面的示例)



如果只用到聚合信息,而不需要源json数据,那么就可以通过"size": 0 来指定不输出源json数据

查询员工的最低、最高和平均工资

GET /employees/_search
{"size": 0, "aggs": {"hs_min_salary": {"min": {"field": "salary"}},"hs_max_salary": {"max": {"field": "salary"}},"hs_avg_salary": {"avg": {"field": "salary"}}}
}

在这里插入图片描述



对salary进行统计

# 对salary进行统计
GET /employees/_search
{"size": 0,"aggs": {"hs_stats_salary": {"stats": {			# 使用stats关键字"field": "salary"}}}
}

在这里插入图片描述



cardinate对搜索结果去重

# cardinate对搜索结果去重
# 需要使用keyword子类型,不能直接使用text类型字段
POST /employees/_search
{"size": 0,"aggs": {"hs_cardinate": {"cardinality": {"field": "job.keyword"}}}
}

在这里插入图片描述



Bucket Aggregation

一些满足特定条件的文档的集合放置到一个桶里,每一个桶关联一个key,类比Mysql中的group by操作。

按照一定的规则,将文档分配到不同的桶中,从而达到分类的目的。

  • Terms,需要字段支持filedata

    • keyword 默认支持fielddata
    • text需要在Mapping 中开启fielddata,会按照分词后的结果进行分桶
  • 数字类型

    • Range / Data Range
    • Histogram(直方图) / Date Histogram
  • 支持嵌套: 也就在桶里再做分桶



获取job的分类信息

其实就是对某个字段分组,然后就各个组下的文档总数

# 获取job字段的分类信息
# text类型的字段需要再mappings中开启fielddata,这里使用job.keyword
GET /employees/_search
{"size": 0,"aggs": {"hs_job": {"terms": {"field": "job.keyword"}}}
}

在这里插入图片描述



聚合可配置属性有:

  • field:指定聚合字段
  • size:指定聚合结果数量
  • order:指定聚合结果排序方式

默认情况下,Bucket聚合会统计Bucket内的文档数量,记为_count,并且按照count降序排序。我们可以指定order属性,自定义聚合的排序方式:

GET /employees/_search
{"size": 0,"aggs": {"hs_job": {"terms": {"field": "job.keyword","size": 5,				# 只显示5条聚合结果"order": {"_count": "asc"		# 按升序排序}}}}
}

在这里插入图片描述



限定聚合范围

其实就是先查询过滤,然后在聚合

# 只对salary在10000元以上的文档聚合
GET /employees/_search
{"size": 0,"query": {"range": {"salary": {"gte": 10000}}}, "aggs": {"hs_job": {"terms": {"field": "job.keyword","size": 10,"order": {"_count": "desc"}}}}
}



注意:对 Text 字段进行 terms 聚合查询,会失败抛出异常

GET /employees/_search
{"size": 0,"aggs": {"hs_job": {"terms": {"field": "job"}}}
}

在这里插入图片描述



对 Text 字段打开 fielddata,支持terms aggregation

# 先查询索引mappings中的数据
GET /employees/_mapping# 再修改对应字段
PUT /employees/_mapping
{"properties": {"job": {"type": "text","fielddata": true,		# 添加fielddata为true"fields": {"keyword": {"type": "keyword","ignore_above": 50}}}}
}

对job.keyword 和 job 进行 terms 聚合,分桶的总数并不一样,如下图所示

在这里插入图片描述



Range & Histogram聚合

  • 按照数字的范围,进行分桶
  • 在Range Aggregation中,可以自定义Key

Range 示例:按照工资的 Range 分桶

# range分桶,可以自己定义 key
POST employees/_search
{"size": 0,"aggs": {"hs_salary_range": {"range": {			# 使用range关键字"field":"salary","ranges":[{"to":10000,"key": "hs_key 0~10000"		# 自定义key},{"from":10000,"to":20000},{"from":20000}]}}}
}

在这里插入图片描述



Histogram示例:按照工资的间隔分桶

# 工资0到10万,以 5000一个区间进行分桶
POST employees/_search
{"size": 0,"aggs": {"hs_salary_histogram": {"histogram": {			# 使用histogram关键字"field": "salary","interval": 5000,		# 指定区间"extended_bounds": {	# 指定总范围"min": 0,"max": 100000}}}}
}

在这里插入图片描述



聚合嵌套

top_hits应用场景: 当获取分桶后,桶内最匹配的顶部文档列表

# 查询不同工种中,年纪最大的3个员工的具体信息
POST employees/_search
{"size": 0,"aggs": {"hs_jobs": {"terms": {"field": "job.keyword"},"aggs": {		# 和terms平级,"hs_old_employee": {"top_hits": {		# 使用top_hits关键字"size": 3,"sort": [{"age": {"order": "desc"}}]}}}}}
}

在这里插入图片描述



# 按照工作类型分桶,并统计工资信息
GET /employees/_search
{"size": 0,"aggs": {"hs_job": {"terms": {"field": "job.keyword"},"aggs": {"hs_salary": {"stats": {"field": "salary"}}}}}
}

在这里插入图片描述



# 多次嵌套。根据工作类型分桶,然后按照性别分桶,计算工资的统计信息
GET /employees/_search
{"size": 0,"aggs": {"hs_job": {"terms": {"field": "job.keyword","size": 10},"aggs": {"hs_gender": {"terms": {"field": "gender","size": 10},"aggs": {"hs_salary": {"stats": {"field": "salary"}}}}}}}
}

在这里插入图片描述



Pipeline Aggregation

支持对聚合分析的结果,再次进行聚合分析。

Pipeline 的分析结果会输出到原结果中,根据位置的不同,分为两类:

  • Sibling - 结果和现有分析结果同级

    • Max,min,Avg , Sum Bucket
    • Stats,Extended Status Bucket
    • Percentiles Bucket
  • Parent -结果内嵌到现有的聚合分析结果之中

    • Derivative(求导)
    • Cumultive Sum(累计求和)
    • Moving Function(移动平均值 )

min_bucket示例

# 平均工资最低的工种
GET /employees/_search
{"size": 0,"aggs": {"hs_job": {"terms": {"field": "job.keyword"},"aggs": {"hs_avg_salary": {"avg": {"field": "salary"}}}},"hs_min_salary_by_job": {		# 这个要和上面的hs_job平级"min_bucket": {		#  使用 min_bucket 关键字  求之前结果的最小值"buckets_path": "hs_job>hs_avg_salary"	 #  通过bucket_path关键字指定路径}}}
}

在这里插入图片描述



Stats示例

# 平均工资的统计分析 , 使用 stats_bucket 关键字
GET /employees/_search
{"size": 0,"aggs": {"hs_job": {"terms": {"field": "job.keyword"},"aggs": {"hs_avg_salary": {"avg": {"field": "salary"}}}},"hs_min_salary_by_job": {"stats_bucket": {		# 使用stats_bucket关键字"buckets_path": "hs_job>hs_avg_salary"}}}
}

在这里插入图片描述



percentiles示例

使用 percentiles_bucket 关键字

# 平均工资的百分位数
GET /employees/_search
{"size": 0,"aggs": {"hs_job": {"terms": {"field": "job.keyword"},"aggs": {"hs_avg_salary": {"avg": {"field": "salary"}}}},"hs_min_salary_by_job": {"percentiles_bucket": {  # 使用 percentiles_bucket 关键字"buckets_path": "hs_job>hs_avg_salary"}}}
}



Cumulative_sum示例

Cumulative_sum 累计求和

GET /employees/_search
{"size": 0,"aggs": {"hs_age": {"histogram": {  			# histogram直方图"field": "age","min_doc_count": 0, "interval": 1			# age年龄字段 每次自增1},"aggs": {"hs_avg_salary": {"avg": {"field": "salary"}},"hs_cumulative_salary": {"cumulative_sum": {"buckets_path": "hs_avg_salary"}}}}}
}



聚合的作用范围

ES聚合分析的默认作用范围是query的查询结果集,同时ES还支持以下方式改变聚合的作用范围:

  • Filter:在聚合前进一步查询过滤条件
  • Post Filter :能找到聚合后,符合指定条件的文档数据
  • Global:即使之前通过查询过滤掉了一些数据,global还是能对所有数据进行聚合操作
#Query
# 先查询 在对满足查询条件的文档进行聚合操作
POST employees/_search
{"size": 0,"query": {"range": {"age": {"gte": 26}}},"aggs": {"hs_jobs": {"terms": {"field": "job.keyword"}}}
}#Filter
# 功能和上方类似,只不过是把查询过滤条件放在了filter中,建议还是使用上方query的方式
POST employees/_search
{"size": 0,"aggs": {"hs_older_person": {			# 对年龄>=26的员工进行聚合操作"filter": {"range": {"age": {"from": 26}}},"aggs": {"jobs": {"terms": {"field": "job.keyword"}}}},"hs_all_jobs": {		# 对所有员工进行聚合操作"terms": {"field": "job.keyword"}}}
}



post_filter. 一条语句,找出所有的job类型。还能找到聚合后符合条件的结果

# 找到聚合后复合条件的文档,显示出来。 这里就是找job为Javascript Programmer的员工信息
POST employees/_search
{"aggs": {"hs_jobs": {"terms": {"field": "job.keyword"}}},"post_filter": {"match": {"job.keyword": "Javascript Programmer"}}
}



global示例

# 大于等于33岁的只有3个员工
# 但是global中还是算的所有员工的平均工资
POST employees/_search
{"size": 0,"query": {"range": {"age": {"gte": 33}}},"aggs": {"hs_jobs": {"terms": {"field":"job.keyword"}},"hs_all":{"global":{},"aggs":{"hs_salary_avg":{"avg":{"field":"salary"}}}}}
}

在这里插入图片描述



排序

指定order,按照count和key进行排序:

  • 默认情况,按照count降序排序
  • 指定size,就能返回相应的桶
#排序 order
#count and key
POST employees/_search
{"size": 0,"query": {		# 查询 过滤不满足的文档"range": {"age": {"gte": 20}}},"aggs": {"hs_jobs": {"terms": {"field":"job.keyword",		# 对job进行分组"order":[{"_count":"asc"},			# 先按count升序排序,再按key降序排序{"_key":"desc"}]}}}
}

在这里插入图片描述



# 也可以对嵌套聚合的值进行排序
# 比如对先按job分组,再求出每组的平均工资,在按平均工资降序排序
POST employees/_search
{"size": 0,"aggs": {"hs_jobs": {"terms": {"field": "job.keyword","order": [{"hs_avg_salary": "desc"}]     # 等同于{"hs_avg_salary.value": "desc"}},"aggs": {"hs_avg_salary": {"avg": {"field": "salary"}}}}}
}

在这里插入图片描述



# 按job分组,再统计每组下的工作。最后按统计结果中的最小值排序
POST employees/_search
{"size": 0,"aggs": {"jobs": {"terms": {"field": "job.keyword","order": [{"hs_stats_salary.min": "desc"}]},"aggs": {"hs_stats_salary": {"stats": {"field": "salary"}}}}}
}

在这里插入图片描述



ES聚合分析不精准原因分析

ElasticSearch在对海量数据进行聚合分析的时候会损失搜索的精准度来满足实时性的需求。

在这里插入图片描述



Terms聚合分析的执行流程:

各个shard分片中先对结果进行处理,然后把数据传输给协调者节点,协调节点再对数据进行汇总归并,再响应请求

在这里插入图片描述

不精准的原因: 数据分散到多个分片,聚合是每个分片的取 Top X,导致结果不精准。

下方案例中,求和返回数据量最大的3个数据,D的数据在两个shard上,结果是6,但是返回的数据中没有D

在这里插入图片描述



思考:如何提高聚合精确度?

方案1:设置主分片为1

注意7.x版本已经默认为1。

适用场景:数据量小的小集群规模业务场景。

对于数据量大的情况,肯定不可能只使用一个shard



方案2:调大 shard_size 值

比如客户一次请求要查询最大的三条记录,但是我每个分片可以给协调节点单分片排序后的 5条数据

设置 shard_size 为比较大的值,官方推荐:size*1.5+10。shard_size 值越大,结果越趋近于精准聚合结果值。此外,还可以通过show_term_doc_count_error参数显示最差情况下的错误值,用于辅助确定 shard_size 大小。

  • size:是聚合结果的返回值,客户期望返回聚合排名前三,size值就是 3。
  • shard_size: 每个分片上聚合的数据条数。shard_size 原则上要大于等于 size

适用场景:数据量大、分片数多的集群业务场景。

测试,使用kibana的测试数据

在这里插入图片描述

使用reindex重建索引,因为kibana提供的测试数据默认是一个shard,我重建索引,指定多个分片

GET kibana_sample_data_flights
PUT /my_flights
{"settings": {"number_of_shards": 20}, "mappings": {"properties" : {"AvgTicketPrice" : {"type" : "float"},"Cancelled" : {"type" : "boolean"},"Carrier" : {"type" : "keyword"},"Dest" : {"type" : "keyword"},"DestAirportID" : {"type" : "keyword"},"DestCityName" : {"type" : "keyword"},"DestCountry" : {"type" : "keyword"},"DestLocation" : {"type" : "geo_point"},"DestRegion" : {"type" : "keyword"},"DestWeather" : {"type" : "keyword"},"DistanceKilometers" : {"type" : "float"},"DistanceMiles" : {"type" : "float"},"FlightDelay" : {"type" : "boolean"},"FlightDelayMin" : {"type" : "integer"},"FlightDelayType" : {"type" : "keyword"},"FlightNum" : {"type" : "keyword"},"FlightTimeHour" : {"type" : "keyword"},"FlightTimeMin" : {"type" : "float"},"Origin" : {"type" : "keyword"},"OriginAirportID" : {"type" : "keyword"},"OriginCityName" : {"type" : "keyword"},"OriginCountry" : {"type" : "keyword"},"OriginLocation" : {"type" : "geo_point"},"OriginRegion" : {"type" : "keyword"},"OriginWeather" : {"type" : "keyword"},"dayOfWeek" : {"type" : "integer"},"timestamp" : {"type" : "date"}}}
}# 使用reindex进行数据迁移
POST _reindex
{"source": {"index": "kibana_sample_data_flights"},"dest": {"index": "my_flights"}
}# 之前的索引就可以删除了
DELETE /kibana_sample_data_flights
GET my_flights/_search
{"size": 0,"aggs": {"hs_weather": {"terms": {"field": "OriginWeather","size": 5,"show_term_doc_count_error": true		# 开启show_term_doc_count_error参数}}}
}GET my_flights/_search
{"size": 0,"aggs": {"hs_weather": {"terms": {"field": "OriginWeather","size": 5,"shard_size": 10,			# 使用shard_size参数"show_term_doc_count_error": true  # 开启show_term_doc_count_error参数}}}
}

在这里插入图片描述

在Terms Aggregation的返回中有两个特殊的数值:

  • doc_count_error_upper_bound : 被遗漏的term 分桶,包含的文档,有可能的最大值

  • sum_other_doc_count: 除了返回结果 bucket的terms以外,其他 terms 的文档总数(总数-返回的总数)



方案3:将size设置为全量值,来解决精度问题

将size设置为2的32次方减去1也就是分片支持的最大值,来解决精度问题。

原因:1.x版本,size等于 0 代表全部,高版本取消 0 值,所以设置了最大值(大于业务的全量值)。

全量带来的弊端就是:如果分片数据量极大,这样做会耗费巨大的CPU 资源来排序,而且可能会阻塞网络。

适用场景:对聚合精准度要求极高的业务场景,由于性能问题,不推荐使用。



方案4:使用Clickhouse/ Spark 进行精准聚合

适用场景:数据量非常大、聚合精度要求高、响应速度快的业务场景。



聚合性能优化

启用 eager global ordinals 提升高基数聚合性能

适用场景:高基数聚合 。

高基数聚合场景中的高基数含义:一个字段包含很大比例的唯一值。



适合启动eager_global_ordinals的场景有:

  • 基于 keyword,ip 等字段的分桶聚合
  • 基于text 字段的分桶聚合(前提条件是:fielddata 开启)。
  • 基于父子文档 Join 类型的 has_child 查询和 父聚合。



global ordinals 使用一个数值代表字段中的字符串值,然后为每一个数值分配一个 bucket(分桶)。

global ordinals 的本质是:

启用 eager_global_ordinals 时,会在刷新分片时构建全局序号。这将构建全局序号的成本从搜索阶段转移到了数据索引化(写入)阶段。



创建索引的同时开启:eager_global_ordinals。

PUT /my-index
{"mappings": {"properties": {"tags": {"type": "keyword","eager_global_ordinals": true 	# 开启eager_global_ordinals}}}
}

开启 eager_global_ordinals 会影响写入性能,因为每次刷新时都会创建新的全局序号。为了最大程度地减少由于频繁刷新建立全局序号而导致的额外开销,请调大刷新间隔 refresh_interval。

动态调整刷新频率的方法如下:

PUT my-index/_settings
{"index": {"refresh_interval": "30s"}
}



本质是:以空间换时间。



插入数据时对索引进行预排序

  • Index sorting (索引排序)可用于在插入时对索引进行预排序,而不是在查询时再对索引进行排序,这将提高范围查询(range query)和排序操作的性能。
  • 在 Elasticsearch 中创建新索引时,可以配置如何对每个分片内的段进行排序。
  • 这是 Elasticsearch 6.X 之后版本才有的特性。
PUT /my_index
{"settings": {"index":{"sort.field": "create_time",  # 指定按照哪个字段进行排序"sort.order": "desc"		# 降序}},"mappings": {"properties": {"create_time":{		# 创建字段,字段名和上方对应"type": "date"}}}
}



注意:预排序将增加 Elasticsearch 写入的成本。

在某些用户特定场景下,开启索引预排序会导致大约 40%-50% 的写性能下降。也就是说,如果用户场景更关注写性能的业务,开启索引预排序不是一个很好的选择。



使用节点查询缓存

节点查询缓存(Node query cache)可用于有效缓存过滤器(filter)操作的结果。

如果多次执行同一 filter 操作,这将很有效,但是即便更改过滤器中的某一个值,也将意味着需要计算新的过滤器结果。

例如,由于 “now” 值一直在变化,因此无法缓存在过滤器上下文中使用 “now” 的查询。

那怎么使用缓存呢?通过在 now 字段上应用 datemath 格式将其四舍五入到最接近的分钟/小时等,可以使此类请求更具可缓存性,以便可以对筛选结果进行缓存。

PUT /my_index/_doc/1
{"create_time":"2022-05-11T16:30:55.328Z"
}#下面的示例无法使用缓存
GET /my_index/_search
{"query":{"constant_score": {"filter": {"range": {"create_time": {"gte": "now-1h","lte": "now"}}}}}
}# 下面的示例就可以使用节点查询缓存。
GET /my_index/_search
{"query":{"constant_score": {"filter": {"range": {"create_time": {"gte": "now-1h/m",     # 在最后增加了/m    m代表分钟"lte": "now/m"}}}}}
}

上述示例中的now-1h/m 就是 datemath 的格式。

如果当前时间 now 是:16:31:29,那么range query 将匹配 my_date 介于:15:31:00 和 15:31:59 之间的时间数据。同理,聚合的前半部分 query 中如果有基于时间查询,或者后半部分 aggs 部分中有基于时间聚合的,建议都使用 datemath 方式做缓存处理以优化性能。



使用分片请求缓存

聚合语句中,设置:size:0,就会使用分片请求缓存缓存结果。size = 0 的含义是:只返回聚合结果,不返回查询结果。

GET /es_db/_search
{"size": 0, 		 # 添加size: 0"aggs": {"hs_remark_agg": {"terms": {"field": "remark.keyword"}}}
}



拆分聚合,使聚合并行化

Elasticsearch 查询条件中同时有多个条件聚合,默认情况下聚合不是并行运行的。当为每个聚合提供自己的查询并执行 msearch 时,性能会有显著提升。因此,在 CPU 资源不是瓶颈的前提下,如果想缩短响应时间,可以将多个聚合拆分为多个查询,

借助:_msearch 实现并行聚合

#常规的多条件聚合实现
GET /employees/_search
{"size": 0,"aggs": {"hs_job_agg": {"terms": {"field": "job.keyword"}},"hs_max_salary":{"max": {"field": "salary"}}}
}
# msearch 拆分多个语句的聚合实现
GET _msearch
{"index":"employees"}
{"size":0,"aggs":{"hs_job_agg":{"terms":{"field": "job.keyword"}}}}
{"index":"employees"}
{"size":0,"aggs":{"hs_max_salary":{"max":{"field": "salary"}}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/399911.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打造高效信息发布平台小程序:设计思路与实践

在当今这个信息爆炸的时代&#xff0c;信息发布平台已成为连接用户与内容的桥梁&#xff0c;小程序以其独特的优势成为众多企业和个人开发者青睐的选择。开发一款专注于信息发布与共享的小程序&#xff0c;旨在为用户打造一个便捷、高效、互动性强的信息获取平台&#xff0c;具…

luckyexcel 编辑预览excel文件

luckyexcel 编辑预览excel文件 支持后端传文件流预览编辑&#xff0c;也支持选择本地文件编辑预览 看效果 上代码 <template><div style"margin: 30px"><div class"button-box2"><div><div style"color: red">…

Windows File Recovery卡在99%怎么解决?实用指南!

为什么会出现“Windows File Recovery卡在99%”的问题&#xff1f; Windows File Recovery&#xff08;Windows文件恢复&#xff09;是微软设计的命令行应用程序。它可以帮助用户从健康/损坏/格式化的存储设备中恢复已删除/丢失的文件。 通过输入相关命令&#xff0c;设置源/…

整理 酷炫 Flutter 开源UI框架 按钮

flutter_percent_indicator Flutter 百分比指示器库 项目地址&#xff1a;https://github.com/diegoveloper/flutter_percent_indicator 项目Demo&#xff1a;https://download.csdn.net/download/qq_36040764/89631340

jenkins 安装以及自动构建maven项目并且运行

在这里找到你对应jdk的版本的jenkins包 War Jenkins Packages 我这里用的使java8,所以下载 https://mirrors.jenkins.io/war-stable/2.60.1/jenkins.war 然后jenkins可以安装到centos系统 在本地windows系统运行命令行 scp C:\Users\98090\Downloads\jenkins.war root@192…

模拟三层--控制层、业务层和数据访问层

三层的概念:https://developer.aliyun.com/article/1390024 一、新建一个项目 我新建好的项目名为spring__ioc_02,然后在 src-main-java 下建立三层&#xff08;数据访问层、业务层和控制层&#xff09;的包 dao、service 和controller、并在包下建立相应的接口和实现类 Proje…

【2】初识JVM

目录 一.什么是JVM 二.JVM的功能 2.1即时编译 三.常见的JVM​编辑 ​编辑 总结​编辑 一.什么是JVM 二.JVM的功能 2.1即时编译 三.常见的JVM 总结

基于Java中的SSM框架实现高校就业管理系统项目【项目源码+论文说明】计算机毕业设计

基于Java中的SSM框架实现高校就业管理系统演示 摘要 本论文主要讲述了基于SSM框架及MySQL数据库实现的就业管理系统的设计和开发过程。本论文中所讲的就业管理系统是通过所学的知识创办一个非商业性的网站平台&#xff0c;使所有想要就业信息查看的高校毕业生们与想要宣传自己…

Spring Web MVC入门(中)

1. 请求 访问不同的路径, 就是发送不同的请求. 在发送请求时, 可能会带⼀些参数, 所以学习Spring的请求, 主要 是学习如何传递参数到后端以及后端如何接收. 传递参数, 咱们主要是使⽤浏览器和Postman来模拟&#xff1b; 1.1 传递单个参数 接收单个参数&#xff0c;在Spring MV…

Spring boot敏感参数加密配置

一&#xff0c;背景 在项目中很多参数会被配置到配置文件中&#xff0c;比如说密钥&#xff0c;用户名&#xff0c;数据库连接&#xff0c;账号密码之类的&#xff0c;如果用明文配置&#xff0c;会有一定的安全风险。为了减小风险&#xff0c;增加对敏感配置数据的加密配置。…

路径规划 | 五种经典算法优化机器人路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 五种经典算法优化机器人路径规划&#xff0c;算法可任意更换&#xff01;地图可修改&#xff01;Matlab语言 1.分为简单路径规划和复杂路径规划两种情景&#xff0c;采用粒子群算法(PSO)&#xff0c;遗传算法(GA)&am…

快速上手Spring Boot

快速上手Spring Boot (qq.com)

YOLO基础-目标检测的性能指标详解与计算方法

目标检测是计算机视觉中的重要任务&#xff0c;主要目的是在图像中识别并定位特定的物体。YOLO&#xff08;You Only Look Once&#xff09;系列模型作为目标检测领域的代表性方法之一&#xff0c;凭借其高效和准确的特点&#xff0c;广泛应用于实际场景中。本文通过详细介绍目…

AI技术在招聘数据分析洞察中的作用

一、引言&#xff1a;AI赋能招聘新纪元 在数字化转型浪潮中&#xff0c;人工智能技术&#xff08;AI&#xff09;正以前所未有的速度渗透至各行各业&#xff0c;其中&#xff0c;招聘领域正经历着一场深刻的变革。传统招聘模式依赖于人工筛选简历、面试评估等低效且主观性强的…

2024年翻译工具新风尚:实时翻译与精准度并进

语言交流的障碍随着全球化的不断深入日益成为连接不同文化和国家的挑战。然而&#xff0c;在科技日新月异的今天&#xff0c;类似谷歌翻译这样的工具正在高速发展这。这次我们来一起探讨深受用户喜欢的翻译工具有哪些。 1.福昕在线翻译 链接直达&#xff1a;https://fanyi.pd…

数据结构 - 位图 | 布隆过滤器

文章目录 一、位图1、位图概念2、实现一个简略的位3、位图的优缺点4、位图的应用场景 二、布隆过滤器1、提出2、概念3、布隆过滤器的实现 三、海量数据处理1、哈希切割2、面试题 一、位图 1、位图概念 位图&#xff08;Bitmap&#xff09;是一种非常高效的数据结构&#xff0c…

MySQL基础练习题38-每位教师所教授的科目种类的数量

目录 题目 准备数据 分析数据 总结 题目 查询每位老师在大学里教授的科目种类的数量。 准备数据 ## 创建库 create database db; use db;## 创建表 Create table If Not Exists Teacher (teacher_id int, subject_id int, dept_id int)## 向表中插入数据 Truncate table…

[Megagon Labs] Annotating Columns with Pre-trained Language Models

Annotating Columns with Pre-trained Language Models 任务定义 输入&#xff1a;一张数据表&#xff0c;但没有表头&#xff0c;只有表中的数据。 输出&#xff1a;每一列数据的数据类型&#xff0c;以及两列数据之间的关系。 数据类型和数据关系都是由训练数据决定的固定…

自建Gitlab和Gitlab runner并推送镜像到Harbor

1. 创建虚拟机 整体规划如下 1.1 创建3台虚拟机 系统版本Centos7.9 设置IP分别为 192.168.200.201 、192.168.200.202、 192.168.200.203 1.2 安装docker 3台虚拟机都安装docker&#xff0c;参考文章 安装docker 1.3 修改daemon.json 修改 /etc/docker/daemon.json 文件…

开源异构数据库同步工具DBSyncer

DBSyncer是一款开源的数据同步中间件&#xff0c;它提供了多种数据库和数据源之间的同步解决方案&#xff0c;包括MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步场景。 以下是对DBSyncer的详细介绍&#xff1a; 一、主要功能与特点 多种…