在Kibana中,我按如下方式创建索引:
PUT cars
{
"mappings":{
"_doc":{
"properties":{
"metadata":{
"type":"nested",
"properties":{
"str_value":{
"type":"keyword"
}
}
}
}
}
}
}
然后我插入三个记录:
POST /cars/_doc/1
{
"metadata": [
{
"key": "model",
"str_value": "Ford"
},
{
"key": "price",
"int_value": 1000
}
]
}
PUT /cars/_doc/2
{
"metadata": [
{
"key": "model",
"str_value": "Ford"
},
{
"key": "price",
"int_value": 2000
}
]
}
PUT /cars/_doc/3
{
"metadata": [
{
"key": "model",
"str_value": "Holden"
},
{
"key": "price",
"int_value": 2500
}
]
}
该模式有点不合常规,但是我以此方式设计了索引,以避免映射爆炸:
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
我想做的就是得到我所有的汽车模型,以及这些模型的价格之和,即福特3000美元,霍顿2500美元。到目前为止,我有:
GET /cars/_search
{
"aggs":{
"metadata":{
"nested":{
"path":"metadata"
},
"aggs":{
"model_filter":{
"filter":{
"term":{
"metadata.key":"model"
}
},
"aggs":{
"model_counter":{
"terms":{
"field":"metadata.str_value",
"size":1000
}
}
}
}
}
}
}
}
这使我成为其中的一部分,因为它返回汽车模型和文件计数:
"aggregations": {
"metadata": {
"doc_count": 6,
"model_filter": {
"doc_count": 3,
"model_counter": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Ford",
"doc_count": 2
},
{
"key": "Holden",
"doc_count": 1
}
]
}
}
}
}
如何修改查询以添加子聚合,该子聚合将显示价格总和,即Ford(两个文档的总和)为3000,Holden(一个文档的总和)为2500
答案 0 :(得分:0)
以下查询应可帮助您找到所需的内容。
我只是为此添加了您的解决方案。我已经使用Reverse Nested Aggregation,然后再次使用Sum Aggregation应用了Nested Aggregation帖子。
因此您的查询层次结构如下:
Nested Aggregation
- Terms Aggregation
- Reverse Nested Aggregation to back to parent doc
- Nested Aggregation to enter into nested price document
- Sum Aggregation to calculate all the prices
POST <your_index_name>/_search
{
"size":0,
"aggs":{
"metadata":{
"nested":{
"path":"metadata"
},
"aggs":{
"model_filter":{
"filter":{
"term":{
"metadata.key":"model"
}
},
"aggs":{
"model_counter":{
"terms":{
"field":"metadata.str_value",
"size":1000
},
"aggs":{
"reverseNestedAgg":{
"reverse_nested":{},
"aggs":{
"metadata":{
"nested":{
"path":"metadata"
},
"aggs":{
"sum":{
"sum":{
"field":"metadata.int_value"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
请注意,我添加了"size": 0
,以便仅返回聚合查询。您可以根据需要进行修改。
{
"took" : 7,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"metadata" : {
"doc_count" : 6,
"model_filter" : {
"doc_count" : 3,
"model_counter" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "Ford",
"doc_count" : 2,
"reverseNestedAgg" : {
"doc_count" : 2,
"metadata" : {
"doc_count" : 4,
"sum" : {
"value" : 3000.0
}
}
}
},
{
"key" : "Holden",
"doc_count" : 1,
"reverseNestedAgg" : {
"doc_count" : 1,
"metadata" : {
"doc_count" : 2,
"sum" : {
"value" : 2500.0
}
}
}
}
]
}
}
}
}
}
请注意,我已经在ES版本7中测试了上述查询。
如果您的文档以以下格式结尾,则以上查询将不起作用。
POST /cars/_doc/1
{
"metadata": [
{
"key": "model",
"str_value": "Ford"
},
{
"key": "price",
"int_value": 1000
},
{
"key": "something else",
"int_value": 1000
}
]
}
// There are three nested documents with two documents having int_value field
我看到您提到过,您希望避免映射爆炸,因此您的架构就是这样。但是,如果发生以上情况,在这种情况下,您可能需要退后一步,重新设计模型,或者让服务层处理此聚合情况。
希望这会有所帮助!