【问题标题】:ElasticSearch aggregates on nested fields嵌套字段上的 ElasticSearch 聚合
【发布时间】:2023-04-03 00:51:01
【问题描述】:

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

{
      "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 查询来搜索“内容”和“标题”字段,并将结果缩小到某个“标签名称”。然后使用聚合来计算该查询中的标记名。

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

【问题讨论】:

  • 索引中的映射是什么样的,即GET {index}/_mapping 返回什么? tags 是否映射为 nested 类型?
  • @RussCam 标签被映射为嵌套。已更新问题以包含映射
  • 你有小例子可以重现吗?看起来您希望获取标签名称中包含术语 competition 并匹配标题或内容中的 FIY 的标签的原始标签名称?这不是你看到的吗?
  • 聚合是根据标题或内容中匹配的 FIY 返回结果,它没有过滤标签竞争。查询工作正常。聚合不正确
  • @RussCam 使用最新版本 5.2。已将文档添加到 gist gist.github.com/anonymous/83bc2b1bfa0ac0d295d42297e1d76c00

标签: elasticsearch nest elasticsearch-dsl


【解决方案1】:

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

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

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

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

Query phase

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

Fetch phase

在获取阶段,与查询阶段的 id 匹配的实际文档被获取并包含在结果中。在您的场景中,您需要在 fetch 阶段运行聚合,仅聚合查询阶段包含的那些文档。

影响聚合考虑哪些文档的唯一方法是在请求的查询中包含额外的查询/过滤器,但到目前为止还没有查询说“排序顺序位置为 1 到 10 的文档”据我所知。

您总是可以在这里为您的特定用例聚合客户端,因为您正在有效地聚合每个标签中的逐字值

【讨论】:

    猜你喜欢
    • 2015-07-30
    • 2017-09-13
    • 1970-01-01
    • 2020-12-21
    • 2018-10-05
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多