弹性搜索:仅聚合特定的嵌套文档

elastic search : Aggregating the specific nested documents only

我想聚合满足给定查询的特定嵌套文档。

让我通过一个例子来解释。我在索引中插入了两条记录:

第一个文档是,

    {
      "project": [
        {
          "subject": "maths",
          "marks": 47
        },
        {
          "subject": "computers",
          "marks": 22
        }
      ]
    }

第二个文件是,

    {
      "project": [
        {
          "subject": "maths",
          "marks": 65
        },
        {
          "subject": "networks",
          "marks": 72
        }
      ]
    }

其中包含主题以及每条记录中的标记。从这些文件中,我需要从给定的文件中平均 maths 个主题。

我试过的查询是:

    {
      "size": 0,
      "aggs": {
        "avg_marks": {
          "avg": {
            "field": "project.marks"
          }
        }
      },
      "query": {
        "bool": {
          "must": [
            {
              "query_string": {
                "query": "project.subject:maths",
                "analyze_wildcard": true,
                "default_field": "*"
              }
            }
          ]
        }
      }
    }

返回的是所有分数平均值的总和结果,这不是必需的。

    {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": 2,
        "max_score": 0,
        "hits": []
      },
      "aggregations": {
        "avg_marks": {
          "value": 51.5
        }
      }
    }

我只需要给定文档的数学科目的平均值,其中预期结果是 56.00

对查询或想法的任何帮助都会有所帮助。 提前致谢。

首先,您需要在映射中指定索引具有如下嵌套字段:

PUT /nested-index {
    "mappings": {
        "document": {
            "properties": {
                "project": {
                    "type": "nested",
                    "properties": {
                        "subject": {
                            "type": "keyword"
                        },
                        "marks": {
                            "type": "long"
                        }
                    }
                }
            }
        }
    }
}

然后插入文档:

PUT nested-index/document/1
{
    "project": [
        {
            "subject": "maths",
            "marks": 47
        },
        {
            "subject": "computers",
            "marks": 22
        }
    ]
}

然后插入第二个文档:

PUT nested-index/document/2
{
    "project": [
        {
            "subject": "maths",
            "marks": 65
        },
        {
            "subject": "networks",
            "marks": 72
        }
    ]
}

然后你做聚合但指定你有这样的嵌套结构:

GET nested-index/_search
{
    "size": 0,
    "aggs": {
        "subjects": {
            "nested": {
                "path": "project"
            },
            "aggs": {
                "subjects": {
                    "terms": {
                        "field": "project.subject",
                        "size": 10
                    },
                    "aggs": {
                        "average": {
                            "avg": {
                                "field": "project.marks"
                            }
                        }
                    }
                }
            }
        }
    }
}

以及为什么您的查询不起作用以及为什么给出该结果是因为当您有嵌套字段并进行平均时,如果在该数组中您有一些关键字并不重要,则它会对一个数组中的所有数字求和仅按一个主题汇总。

因此,如果您有这两个文档,因为在两个文档中您都有数学科目,平均计算如下:

(47 + 22 + 65 + 72) / 4 = 51.5

如果你想要网络的平均值,它会 return 你(因为在一个文档中你有网络,但它会对数组中的所有值进行平均):

65 + 72 = 68.5

所以在这种情况下你需要使用嵌套结构。

如果你只对一个主题感兴趣,你可以只对等于这样的主题进行聚合(主题等于 "maths"):

GET nested-index/_search
{
    "size": 0,
    "aggs": {
        "project": {
            "nested": {
                "path": "project"
            },
            "aggs": {
                "subjects": {
                    "filter": {
                        "term": {
                            "project.subject": "maths"
                        }
                    },
                    "aggs": {
                        "average": {
                            "avg": {
                                "field": "project.marks"
                            }
                        }
                    }
                }
            }
        }
    }
}