首页 > 解决方案 > 如何对 Elasticsearch 中的对象列表执行聚合(例如 avg)?

问题描述

我在 Elasticsearch 中有以下形式的数据:

[
    {
        "id": 1,
        "name": "abc",
        "score": 10,
        "values": [
            {
                "v1": 1,
                "v2": 2
            }
        ]
    },
    {
        "id": 2,
        "name": "def",
        "score": 20,
        "values": [
            {
                "v1": 3,
                "v2": 4
            }
        ]
    }
]

目前,我正在计算score使用以下代码的平均值:

s = Search(using=es, index=index).query(Q(query))
s.aggs.bucket('average_score', 'avg', field='score') # average_score = 15

现在我希望计算平均值v1v2使用elasticsearch_dsl,但我不知道如何进行嵌套聚合。在这个例子中,v1 = 2v2 = 3。请帮忙。提前致谢!

编辑: 不幸的是,这里values是一个对象而不是嵌套的。

标签: elasticsearchelasticsearch-aggregationelasticsearch-dslaws-elasticsearch

解决方案


不知道如何在您的 DSL 中执行此操作,但这里是原始步骤。


映射:

PUT avgs/
{
  "mappings": {
    "properties": {
      "values": {
        "type": "nested",
        "properties": {
          "v1": {
            "type": "integer"
          },
          "v2": {
            "type": "integer"
          }
        }
      }
    }
  }
}

索引:

POST avgs/_doc
{
  "id": 1,
  "name": "abc",
  "score": 10,
  "values": [
    {
      "v1": 1,
      "v2": 2
    }
  ]
}

POST avgs/_doc
{
  "id": 2,
  "name": "def",
  "score": 20,
  "values": [
    {
      "v1": 3,
      "v2": 4
    }
  ]
}

查询:

GET avgs/_search
{
  "size": 0,
  "aggs": {
    "avg_v1": {
      "nested": {
        "path": "values"
      },
      "aggs": {
        "nested_v1": {
          "avg": {
            "field": "values.v1"
          }
        }
      }
    },
    "avg_v2": {
      "nested": {
        "path": "values"
      },
      "aggs": {
        "nested_v2": {
          "avg": {
            "field": "values.v2"
          }
        }
      }
    }
  }
}

产量:

...
  "aggregations" : {
    "avg_v2" : {
      "doc_count" : 2,
      "nested_v2" : {
        "value" : 3.0
      }
    },
    "avg_v1" : {
      "doc_count" : 2,
      "nested_v1" : {
        "value" : 2.0
      }
    }
  }
...

推荐阅读