ElasticSearch在嵌套字段上聚合

时间:2017-03-17 16:09:36

标签: elasticsearch nest elasticsearch-dsl

我有一个具有以下结构的索引。

{
      "title": "Your top FIY tips",
      "content": "Fix It Yourself in April 2012.",
      "tags": [
        {
          "tagName": "Fix it yourself"
        },
        {
          "tagName": "customer tips"
        },
        {
          "tagName": "competition"
        }
      ]  
}

映射看起来像

{
"articles": {
"mappings": {
  "article": {
    "properties": {
      "content": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "tags": {
        "type": "nested",
        "properties": {
          "tagName": {
            "type": "text",
            "fields": {
              "raw": {
                "type": "keyword"
              }
            }
          }
        }
      }
    }
  }
}
}

我正在使用以下DSL查询来搜索"内容"和"标题"字段并将结果缩小到某个" tagName"。然后使用聚合来计算该查询中的tagNames。

GET /articles/_search
{
  "from": 1,
  "size": 10,
  "aggs": {
    "tags": {
      "nested": {
        "path": "tags"
      },
      "aggs": {
        "tags-tagnames": {
          "terms": {
            "field": "tags.tagName.raw"
          }
        }
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "FIY",
            "fields": [
              "title",
              "content"
            ]
          }
        },
        {
          "nested": {
            "query": {
              "terms": {
                "tags.tagName": [
                  "competition"
                ]
              }
            },
            "path": "tags"
          }
        }
      ]
    }
  }
}

" tagNames"的搜索查询和过滤器工作良好。然而,聚合不是很有效。它似乎不包括结果中的嵌套查询数据。返回的汇总结果仅基于多重匹配搜索。

如何在聚合中包含嵌套查询。

的示例文件

https://gist.github.com/anonymous/83bc2b1bfa0ac0d295d42297e1d76c00

1 个答案:

答案 0 :(得分:1)

经过讨论,我想我更了解你的问题:

  

您希望仅对基于查询中指定的"from""size"包含的那些文档运行聚合。

"from"仅影响为查询返回的匹配,聚合计算与查询匹配的所有文档。

由于Elasticsearch的工作方式,目前无法实现您的目标。 Elasticsearch中的搜索请求有两个阶段:

Query phase

查询阶段是查询群集中的所有分片时,将返回与查询匹配的文档的文档ID。 聚合也会在查询阶段运行。

Fetch phase

在获取阶段,将获取与查询阶段中的ID匹配的实际文档,并将其包含在结果中。在您的方案中,您需要聚合在获取阶段运行,以便仅聚合查询阶段中包含的那些文档。

影响聚合考虑哪些文档的唯一方法是在请求的查询中包含其他查询/过滤器,但是没有查询在排序顺序位置1到10中的"文档#34;据我所知。

您可以在此处聚合特定用例的客户端,因为您正在有效地汇总每个标记中的逐字值