Filtered nested aggregation in ElasticSearch?

浪子不回头ぞ 提交于 2019-12-12 06:18:37

问题


I have following document list in ElasticSearch (where scores are nested):

{
    'type': 'typeA',
    'scores': [
       {'type': 'A', 'val': 45},
       {'type': 'A', 'val': 55},
       {'type': 'B', 'val': 65},
    ]
},
{
    'type': 'typeA',
    'scores': [
       {'type': 'A', 'val': 55},
       {'type': 'A', 'val': 50},
       {'type': 'A', 'val': 57},
    ]
},
{
    'type': 'typeB',
    'scores': [
       {'type': 'B', 'val': 40},
       {'type': 'A', 'val': 50},
       {'type': 'A', 'val': 60},
    ]
}

Is it possible to have a query that returns average scores per type, but only if scores.type is "A"?

Explanation (if I did it manually):

1) filter only "A" scores (simplified):

{'type': 'typeA', 'scores': [45, 55]},
{'type': 'typeA', 'scores': [55, 50, 57]},
{'type': 'typeB', 'scores': [50, 60]},

2) find AVG per document:

{'type': 'typeA', 'avg': 50}, // (45+55) / 2
{'type': 'typeA', 'avg': 54}, // (55+50+57) / 3
{'type': 'typeB', 'avg': 55}, // (50 + 60) / 2

3) Final aggregation per type:

'typeA' : 52, // (50+54) / 2
'typeB': 55, // (55) / 1

Is it possible or I should stick to client side for this?


回答1:


Yes, it is definitely possible to do it with a combination of terms, nested and avg aggregations, like this:

{
  "size": 0,
  "aggs": {
    "top_level_type": {                    <---- group by top-level type
      "terms": {
        "field": "type"
      },
      "aggs": {
        "nest": {
          "nested": {                      <---- "dive" your nested scores
            "path": "scores"
          },
          "aggs": {
            "type_filter": {
              "filter": {                  <---- filter only score type A
                "term": {
                  "scores.type": "A"
                }
              },
              "aggs": {
                "average": {
                  "avg": {                 <---- compute the average of the score values
                    "field": "scores.val"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

The resulting values would look like this:

{
  ...
  "aggregations" : {
    "top_level_type" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [ {
        "key" : "typea",
        "doc_count" : 2,
        "nest" : {
          "doc_count" : 6,
          "type_filter" : {
            "doc_count" : 5,
            "average" : {
              "value" : 52.4
            }
          }
        }
      }, {
        "key" : "typeb",
        "doc_count" : 1,
        "nest" : {
          "doc_count" : 3,
          "type_filter" : {
            "doc_count" : 2,
            "average" : {
              "value" : 55.0
            }
          }
        }
      } ]
    }
  }
}


来源:https://stackoverflow.com/questions/32132061/filtered-nested-aggregation-in-elasticsearch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!