ElasticSearch 聚合嵌套字段作为父文档的一部分
ElasticSearch aggregate nested fields as part of parent document
我有 Product
个实体和嵌套的 Variation
个实体的索引。 Product
实体由 Id
、Title
和嵌套变体组成。 Variation
实体由 Color
、Size
和 Price
字段组成。我需要按 Color
、Size
和 Price
字段汇总搜索结果,以获得每个颜色、尺寸和价格组的产品数量。如果我对这些字段使用嵌套聚合,我会得到正确的 bucket,但 bucket 中的文档数量是每个 bucket 的 Variation
个实体数。但我需要获取每个存储桶的 Product
个实体(根文档)的数量。
例如,第一个产品有变体(红色、小号、10 美元)、(绿色、小号、10 美元)、(红色、中号、11 美元),第二个产品有变体(绿色、中号、15 美元)。嵌套聚合 returns 2 for red
and 2 for small
because 2 variations has red
color and small
size.但是我需要每个桶的产品(根实体)数量,red
应该是 1,small
.
应该是 1
由于其他要求,我也不能使用子文档代替嵌套文档。
如何编写查询以获得此结果?
这是映射:
{
"product": {
"properties": {
"id": {
"type": "long"
},
"title": {
"type": "string"
},
"brand": {
"type": "string"
},
"variations": {
"type": "nested",
"properties": {
"id": {
"type": "long"
},
"colour": {
"type": "string"
},
"size": {
"type": "string"
},
"price": {
"type": "double"
}
}
},
"location": {
"type": "geo_point"
}
}
}
}
这是一个查询
{
"aggs": {
"Variations": {
"nested": {
"path": "variations"
},
"aggs": {
"Colous": {
"terms": {
"field": "variations.colour"
}
},
"Sizes": {
"terms": {
"field": "variations.size"
}
}
}
},
"Brands": {
"terms": {
"field": "brand"
}
}
},
"query": {
"match_all": {}
}
}
Brand
聚合效果很好,因为它获取每个组的根文档数,但嵌套聚合 return 嵌套文档数而不是根文档数。
您以正确的方式解决了问题。现在您可以简单地使用 reverse_nested
aggregation 来 "join back" 到根产品,并为您的变体获取每个匹配产品的数量。
{
"aggs": {
"Variations": {
"nested": {
"path": "variations"
},
"aggs": {
"Colous": {
"terms": {
"field": "variations.colour"
},
"aggs": {
"product_count": { <--- add this reverse nested agg
"reverse_nested": {}
}
}
},
"Sizes": {
"terms": {
"field": "variations.size"
},
"aggs": {
"product_count": { <--- add this reverse nested agg
"reverse_nested": {}
}
}
}
}
},
"Brands": {
"terms": {
"field": "brand"
}
}
},
"query": {
"match_all": {}
}
}
在回复中,您会看到:
- 2 个产品匹配
colour: green
- 1 个产品匹配
colour: red
- 2 个产品匹配
size: medium
- 1 个产品匹配
size: small
我有 Product
个实体和嵌套的 Variation
个实体的索引。 Product
实体由 Id
、Title
和嵌套变体组成。 Variation
实体由 Color
、Size
和 Price
字段组成。我需要按 Color
、Size
和 Price
字段汇总搜索结果,以获得每个颜色、尺寸和价格组的产品数量。如果我对这些字段使用嵌套聚合,我会得到正确的 bucket,但 bucket 中的文档数量是每个 bucket 的 Variation
个实体数。但我需要获取每个存储桶的 Product
个实体(根文档)的数量。
例如,第一个产品有变体(红色、小号、10 美元)、(绿色、小号、10 美元)、(红色、中号、11 美元),第二个产品有变体(绿色、中号、15 美元)。嵌套聚合 returns 2 for red
and 2 for small
because 2 variations has red
color and small
size.但是我需要每个桶的产品(根实体)数量,red
应该是 1,small
.
由于其他要求,我也不能使用子文档代替嵌套文档。
如何编写查询以获得此结果?
这是映射:
{
"product": {
"properties": {
"id": {
"type": "long"
},
"title": {
"type": "string"
},
"brand": {
"type": "string"
},
"variations": {
"type": "nested",
"properties": {
"id": {
"type": "long"
},
"colour": {
"type": "string"
},
"size": {
"type": "string"
},
"price": {
"type": "double"
}
}
},
"location": {
"type": "geo_point"
}
}
}
}
这是一个查询
{
"aggs": {
"Variations": {
"nested": {
"path": "variations"
},
"aggs": {
"Colous": {
"terms": {
"field": "variations.colour"
}
},
"Sizes": {
"terms": {
"field": "variations.size"
}
}
}
},
"Brands": {
"terms": {
"field": "brand"
}
}
},
"query": {
"match_all": {}
}
}
Brand
聚合效果很好,因为它获取每个组的根文档数,但嵌套聚合 return 嵌套文档数而不是根文档数。
您以正确的方式解决了问题。现在您可以简单地使用 reverse_nested
aggregation 来 "join back" 到根产品,并为您的变体获取每个匹配产品的数量。
{
"aggs": {
"Variations": {
"nested": {
"path": "variations"
},
"aggs": {
"Colous": {
"terms": {
"field": "variations.colour"
},
"aggs": {
"product_count": { <--- add this reverse nested agg
"reverse_nested": {}
}
}
},
"Sizes": {
"terms": {
"field": "variations.size"
},
"aggs": {
"product_count": { <--- add this reverse nested agg
"reverse_nested": {}
}
}
}
}
},
"Brands": {
"terms": {
"field": "brand"
}
}
},
"query": {
"match_all": {}
}
}
在回复中,您会看到:
- 2 个产品匹配
colour: green
- 1 个产品匹配
colour: red
- 2 个产品匹配
size: medium
- 1 个产品匹配
size: small