快速做网站优化,wordpress 删除数据库,去哪里做网站,个人做跨境电商网站前一篇已经系统介绍过查询语法#xff0c;详细可直接看上一篇文章#xff08;理解DSL语法#xff08;一#xff09;#xff09;#xff0c;本篇主要介绍DSL中的另一部分#xff1a;聚合
理解Es中的聚合
虽然Elasticsearch 是一个基于 Lucene 的搜索引擎#xff0c;但…前一篇已经系统介绍过查询语法详细可直接看上一篇文章理解DSL语法一本篇主要介绍DSL中的另一部分聚合
理解Es中的聚合
虽然Elasticsearch 是一个基于 Lucene 的搜索引擎但也提供了聚合aggregations的功能允许用户对数据进行统计和分析。聚合可以按照不同的维度对数据进行分组和汇总从而得到有意义的统计信息。这也是Es很多场景下被当作分析工具使用的原因。
聚合语法
使用上来讲es的聚合就相当于SQL中的group by在DSL中主要使用aggs关键字和size关键字来控制
{size:0,aggs:{TestName:{ //自定义的聚合名称term:{ //聚合类型关键字根据聚合类型来field:title //需要聚合的字段}}}
}
这里着重说一下size关键字如果单纯进行聚合而不需要实际数据最好这里size设置为0设置size为0在进行聚合时会默认触发Es的缓存机制能够很有效的提升性能。
当然聚合也可以搭配查询query使用即对查询的数据进行聚合,例如我们对最近一天的文章聚合一下标题
{query:{bool:{filter:[{range:{ create_time:{gte:now - 1d,lte:now}}}]}}size:0,aggs:{TestName:{ //自定义的聚合名称term:{ //聚合类型关键字根据聚合类型来field:title //需要聚合的字段}}}
}
这里Es收到请求后会先根据query中的条件去检索满足创建时间在近一天内的所有文档然后对这些文档进行桶聚合以title字段为桶将title内容一致的文档放入桶内。
聚合的种类
总的来看Es的聚合可以分为四类即Bucketing Aggregations、Metric Aggregations、Matrix Aggregations、Pipeline Aggregations。 Bucketing Aggregations
将数据分桶类似于 SQL 中的 GROUP BY。例如可以根据某个字段的不同值将数据分组然后对每个分组进行统计对于字段和内容都有一定的限制。
常用的聚合关键字有
关键字描述适用字段类型TermsTerms 聚合根据指定字段的确切值将文档分组。它类似于 SQL 中的 GROUP BY 语句。keyword Histogram直方图聚合将数值字段划分为指定间隔的桶并计算每个桶中的文档数量。 数值类型 integer、float、double 、 long Date Histogram日期直方图聚合类似于直方图聚合但它专门用于日期字段允许你根据时间间隔如天、周、月等来分组数据dateRange范围聚合允许你根据指定的范围将数据分组每个范围定义了上界和下界。数值类型 integer、float、double 、 long 和dateIP Range IP 范围聚合允许你根据 IP 地址的范围将数据分组。ipDate Range日期范围聚合是范围聚合的日期版本专门用于日期字段。dateFilter/Filters过滤器聚合根据一个或多个过滤器条件将数据分组每个过滤器条件定义了一个桶。可以应用于任何类型的字段但通常与布尔查询结合使用来定义过滤器条件。Nested 嵌套聚合应用于嵌套字段它允许你根据嵌套对象中的字段值对嵌套文档进行分组。object或nested
详细的可查阅ElasticSearch的官网这里仅列出常用的我们假设Es中存在以下一个数据集合
[{name: Book A, category: Fiction, price: 9.99, publish_date: 2020-01-01},{name: Book B, category: Science, price: 15.00, publish_date: 2021-06-15},{name: Book C, category: Fiction, price: 12.50, publish_date: 2022-03-10},{name: Book D, category: Education, price: 8.50, publish_date: 2019-09-20},{name: Book E, category: Science, price: 20.00, publish_date: 2023-01-05}
]
并针对该数据集进行相关的聚合样例 Terms Aggregation聚合
查看有多少种category以及每种的文档数量。
示例
{size:0,aggs: {genres: {terms: {field: category // genre必须为keyword类型size:3 //根据文档数量倒叙展示条数默认不填写则仅展示10个}}}
}//输出
{category: {buckets: [{key: Fiction, doc_count: 2},{key: Science, doc_count: 2},{key: Education, doc_count: 1}]}
}
Histogram Aggregation 聚合
按价格区间聚合书籍
{size:0,aggs: {price_distribution: {histogram: {field: price,interval: 5 //以5元为一个段}}}
}//输出
{aggregations: {price_distribution: {buckets: [{ key: 5, doc_count: 1 },{ key: 10, doc_count: 2 },{ key: 15, doc_count: 2 }]}}
}
Date Histogram Aggregation 聚合
按年份查看出版书籍的数量
{size:0,aggs: {books_over_time: {date_histogram: {field: publish_date,calendar_interval: year //查询区间可以指定单位}}}
}//输出{aggregations: {books_over_time: {buckets: [{ key_as_string: 2019, doc_count: 1 },{ key_as_string: 2020, doc_count: 1 },{ key_as_string: 2021, doc_count: 1 },{ key_as_string: 2022, doc_count: 1 },{ key_as_string: 2023, doc_count: 1 }]}}
}
其中对于date_histogram使用较多这里单独列一下关于date_histogram的相关参数 calendar_interval按照日历时间间隔如年、季度、月、周、日等来创建桶。 fixed_interval按照固定时间间隔如1小时、5分钟等来创建桶不考虑日历界限。 min_doc_count设置为 0 或更大的值以忽略那些文档计数小于该值的桶。 extended_bounds允许聚合查询返回超出正常查询范围之外的桶例如在直方图的开始或结束之前添加额外的桶。 order指定桶的排序方式可以是 asc升序或 desc降序。 format自定义日期格式用于指定桶的 key 值的日期格式。 time_zone指定时区来应用到聚合上特别是对于固定间隔的聚合。 pre_zone 和 post_zone与 extended_bounds 结合使用指定额外桶的时区。
{size: 0,aggs: {publish_monthly: {date_histogram: {field: publish_date,calendar_interval: month, // 每月一个桶min_doc_count: 1, // 只包括至少有一个文档的桶extended_bounds: {min: 2019-01-01,max: 2023-12-31}, // 设置聚合的最小和最大界限order: desc, // 桶按降序排序format: yyyy-MM, // 桶 key 的格式time_zone: Europe/Berlin // 使用柏林时区}}}
} Range Aggregation聚合
查看价格区间内书籍的数量
{size:0,aggs: {price_ranges: {range: {field: price,ranges: [{ from: 0, to: 10 },{ from: 10, to: 20 }]}}}
}//输出
{aggregations: {price_ranges: {buckets: [{ from: 0, to: 10, doc_count: 2 },{ from: 10, to: 20, doc_count: 3 }]}}
}
Filters Aggregation聚合
同时筛选 Fiction 和 Science 类别的书籍并分别计算数量。
{size:0,aggs: {category_filters: {filters: {filters: {Fiction: {term: {category.keyword: Fiction}},Science: {term: {category.keyword: Science}}}}}}
}
//输出
{aggregations: {category_filters: {buckets: {Fiction: { doc_count: 2 },Science: { doc_count: 2 }}}}
}
这里特殊说明一下针对以上场景也可以使用
{query: {bool: {filter: [{terms: {category: [Fiction, Science]}}]}},size: 0,aggs: {category: {terms: {field: category}}}
}
不同的是使用这种聚合Es的需要进行两次操作即先根据query条件进行数据查询再对查询结果进行聚合而Filters聚合则只有一次操作。在相同场景下考虑性能的话使用 filters 聚合可能在某些情况下更有效率因为它可以利用 Elasticsearch 的缓存机制特别是当这些特定的过滤条件经常被查询时。
Composite Aggregation聚合
按 category 和 publish_date 的每个月份组合聚合书籍。
{size: 0,aggs: {category_date_composite: {composite: {sources: [{ category: { terms: { field: category.keyword } } },{ date: { date_histogram: { field: publish_date, calendar_interval: month } } }],size: 10}}}
}
//输出
{composite_of_category_and_date: {buckets: [{key: {category: Fiction, date: 2020-01}, doc_count: 1},{key: {category: Fiction, date: 2022-03}, doc_count: 1},{key: {category: Science, date: 2021-06}, doc_count: 1},{key: {category: Science, date: 2023-01}, doc_count: 1}]}
}
Metric Aggregations
对数据进行数学运算如计算平均值、总和、最小值、最大值等。此类大多对数字类型的字段进行聚合。
关键字描述Sum Aggregation计算数值字段的总和Avg Aggregation 计算数值字段的平均值 Min Aggregation 找出数值字段中的最小值 Max Aggregation 找出数值字段中的最大值 Stats Aggregation 返回字段的多个统计度量包括最小值、最大值、平均值和总和。 Cardinality Aggregation 计算字段中唯一值的近似数量对于大数据集非常有用因为它比value_count更高效。
一般配合桶查询使用对标的是SQL中的SUM、MAX等数学函数
Cardinality Aggregation
查看一共有多少文档
{size:0,aggs: {countALl: {cardinality: {field: _id}}}
}//输出
{aggregations: {countALl: {value: 3}}
}
Min/Max Aggregation
//查看书籍最贵的价格
{size:0,aggs: {maximum_price: {max: {field: price}}}
}
//输出
{aggregations: {maximum_price: {value: 20.0}}
}//查看书籍最便宜的价格
{size:0,aggs: {min_price: {min: {field: price}}}
}
//输出
//输出
{aggregations: {min_price: {value: 5.0}}
}Sum/Avg Aggregation
//对库内书籍价格求和
{aggs: {all_price: {sum: {field: price}}}
}//输出
{aggregations: {all_price: {value: 13.398}}
}//对库内书籍价格求均值
{aggs: {average_price: {avg: {field: price}}}
}//输出
{aggregations: {average_price: {value: 13.398}}
}
Stats Aggregation
查看价格的综合统计
{size:0,aggs: {price_stats: {stats: {field: price}}}
}//输出
{aggregations: {price_stats: {count: 5,min: 8.5,max: 20.0,avg: 13.398,sum: 66.99}}
} 聚合嵌套
语法格式为
{size:0,aggs:{One:{ // 一层桶名称terms:{field:fielda},aggs:{ //一层桶下二层聚合} }}
}
以书籍书籍为例查看每类书籍的平均价格则可以先对书籍类型进行terms聚合再在terms桶内获取桶内书籍的平均价格
//DSL
{size: 0,aggs: {categories: {terms: {field: keyword},aggs: {average_price: {avg: {field: price}}}}}
}//输出结果
{aggregations: {categories: {buckets: [{key: Fiction,doc_count: 2,average_price: {value: 11.245}},{key: Science,doc_count: 2,average_price: {value: 17.5}},{key: Education,doc_count: 1,average_price: {value: 8.5}}]}}
}
也可以查看发布年限每年里发布书籍的总价格
{size: 0,aggs: {publish_years: {date_histogram: {field: publish_date,calendar_interval: year},aggs: {total_price: {sum: {field: price}}}}}
}//输出
{aggregations: {publish_years: {buckets: [{key_as_string: 2019,key: 1577836800000,doc_count: 1,total_price: {value: 8.5}},{key_as_string: 2020,key: 1609459200000,doc_count: 1,total_price: {value: 9.99}},{key_as_string: 2021,key: 1609459200000,doc_count: 1,total_price: {value: 15.0}},{key_as_string: 2022,key: 1640995200000,doc_count: 1,total_price: {value: 12.5}},{key_as_string: 2023,key: 1672531200000,doc_count: 1,total_price: {value: 20.0}}]}}
}