这几天在做es的聚合查询,对那种一对多的产品数据查询的时候遇到了一些问题,做一下记录
1.es文档数据结构如下
=====doc 文档一
{
"id": "IEO29R12KN912NDF893",
"products": [
{
"product_name": "电视机",
"budget": 2000
},
{
"product_name": "手机",
"budget": 851
}
],
"publish_year": "2020"
}
=====doc 文档二
{
"id": "IQFJ019238AHJDFK1L9",
"products": [
{
"product_name": "电视机",
"budget": 2000
},
{
"product_name": "相机",
"budget": 5000
},
{
"product_name": "扑克牌",
"budget": 2
}
],
"publish_year": "2019"
}
2.我的查询需求结果是
针对每个产品名称[product_name]进行分组,并对预算[budget]求和
3.我期望的查询结果
产品名称 | 预算 |
---|---|
电视机 | 4000 |
手机 | 851 |
相机 | 5000 |
扑克牌 | 2 |
4.错误的es查询以及结果
4.1查询的es语句和结果
es查询语句==简化版
{
"from": 0,
"size": 14,
"aggs": {
"aggs_of_product": {
"terms": {
"field": "products.product_name.keyword"
},
"aggs": {
"aggs_sum_of_budget": {
"sum": {
"field": "products.budget"
}
}
}
}
}doc 文档二
}
es查询的结果==简化版
{
"aggregations": {
"aggs_of_product": {
"buckets": [
{
"key": "电视机",
"doc_count": 2,
"aggs_sum_of_budget": {
"value": 9853
}
},
{
"key": "手机",
"doc_count": 1,
"aggs_sum_of_budget": {
"value": 2851
}
},
{
"key": "相机",
"doc_count": 1,
"aggs_sum_of_budget": {
"value": 7002
}
},
{
"key": "扑克牌",
"doc_count": 1,
"aggs_sum_of_budget": {
"value": 7002
}
}
]
}
}
}
4.2 错误的原因
注意电视机的doc_count为2,这里我们可以根据电视,相机,扑克牌的预算和可以得出结论。以相机为例:他计算的sum值是把命中相机的[doc 文档二]下面的产品的budget预算全部求和了,这里的es聚合查询在这里就不适用了。
如果一个文档里面只有一个产品的话,那这个es查询语句查出的结果就是正确的。
5.解决方案
在经过多次的google和百度后我发现了一个问题,就是我的计算思路是没问题的,主要问题还在在products的这个字段的类型,最开始products的类型是默认的,后面需要把他改为nested[嵌套]类型的才可以
5.1 字段索引mapping的修改
之前products的mapping
{
"mappings": {
"properties": {
"products": {
"properties": {
"product_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"budget": {
"type": "float"
}
}
}
}
}
}
修改products之后的mapping
把products的字段类型改为nested嵌套类型的。
多一个 “type”: “nested”文章来源:https://www.toymoban.com/news/detail-603093.html
{
"mappings": {
"properties": {
"products": {
"type": "nested",
"properties": {
"product_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"budget": {
"type": "float"
}
}
}
}
}
}
5.2 修改后的es查询语句
{
"aggs": {
"nested_name": {
"nested": {
"path": "products"
},
"aggs": {
"aggs_of_product": {
"terms": {
"field": "products.product_name.keyword"
},
"aggs": {
"aggs_sum_of_budget": {
"sum": {
"field": "products.budget"
}
}
}
}
}
}
}
}
5.3 修改后的查询结果
{
"aggregations": {
"aggr_field_product": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 36126,
"buckets": [
{
"key": "电视机",
"doc_count": 2,
"sum_eventTime": {
"value": 4000
}
},
{
"key": "手机",
"doc_count": 1,
"sum_eventTime": {
"value": 851
}
},
{
"key": "相机",
"doc_count": 1,
"sum_eventTime": {
"value": 5000
}
},
{
"key": "扑克牌",
"doc_count": 1,
"sum_eventTime": {
"value": 2
}
}
]
}
}
}
6.参考资料
stackoverflow-nested-array-of-objects-aggregation-in-elasticsearch
Elasticsearch 7.x Nested 嵌套类型查询-知乎
Elasticsearch Nested类型深入详解文章来源地址https://www.toymoban.com/news/detail-603093.html
到了这里,关于Elasticsearch 基于 array 结构 的nested类型的索引的聚合查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!