如何获得具有多个字段的 Elasticsearch 聚合
Posted
技术标签:
【中文标题】如何获得具有多个字段的 Elasticsearch 聚合【英文标题】:How to get an Elasticsearch aggregation with multiple fields 【发布时间】:2015-08-24 01:36:21 【问题描述】:我正在尝试查找与当前正在查看的标签相关的标签。我们索引中的每个文档都被标记。每个标签由两部分组成 - 一个 ID 和文本名称:
...
meta:
...
tags: [
id: 123,
name: 'Biscuits'
,
id: 456,
name: 'Cakes'
,
id: 789,
name: 'Breads'
]
要获取相关标签,我只是查询文档并获取它们的标签聚合:
"query":
"bool":
"must": [
"match":
"item.meta.tags.id": "123"
,
...
]
,
"aggs":
"baked_goods":
"terms":
"field": "item.meta.tags.id",
"min_doc_count": 2
这非常有效,我得到了我想要的结果。但是,我需要标签 ID 和 名称来做任何有用的事情。我已经探索了如何做到这一点,解决方案似乎是:
-
索引时合并字段
将字段组合在一起的脚本
嵌套聚合
选项一和二对我来说不可用,所以我一直选择 3,但它没有以预期的方式响应。给定以下查询(仍在搜索也标记为“饼干”的文档):
...
"aggs":
"baked_goods":
"terms":
"field": "item.meta.tags.id",
"min_doc_count": 2
,
"aggs":
"name":
"terms":
"field": "item.meta.tags.name"
我会得到这个结果:
...
"aggregations":
"baked_goods":
"buckets": [
"key": "456",
"doc_count": 11,
"name":
"buckets": [
"key": "Biscuits",
"doc_count": 11
,
"key": "Cakes",
"doc_count": 11
]
]
嵌套聚合包括搜索词和我所追求的标签(按字母顺序返回)。
我试图通过在嵌套聚合中添加 exclude
来缓解这种情况,但这会使查询速度减慢太多(对于 500000 个文档,大约是 100 倍)。到目前为止,最快的解决方案是手动对结果进行重复数据删除。
在响应中获取包含标签 ID 和标签名称的标签聚合的最佳方法是什么?
感谢您到此为止!
【问题讨论】:
【参考方案1】:从外观上看,您的tags
不是nested
。
要使此聚合起作用,请使用you need it nested
,以便id
和name
之间存在关联。没有nested
,id
s 的列表只是一个数组,name
s 的列表是另一个数组:
"item":
"properties":
"meta":
"properties":
"tags":
"type": "nested", <-- nested field
"include_in_parent": true, <-- to, also, keep the flat array-like structure
"properties":
"id":
"type": "integer"
,
"name":
"type": "string"
另外,请注意,我已将这一行 "include_in_parent": true
添加到映射中,这意味着您的 nested
标记也将表现得像一个“平面”类数组结构。
因此,到目前为止,您在查询中的所有内容仍然可以正常工作,而无需对查询进行任何更改。
但是,对于您的这个特定查询,聚合需要更改为以下内容:
"aggs":
"baked_goods":
"nested":
"path": "item.meta.tags"
,
"aggs":
"name":
"terms":
"field": "item.meta.tags.id"
,
"aggs":
"name":
"terms":
"field": "item.meta.tags.name"
结果是这样的:
"aggregations":
"baked_goods":
"doc_count": 9,
"name":
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
"key": 123,
"doc_count": 3,
"name":
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
"key": "biscuits",
"doc_count": 3
]
,
"key": 456,
"doc_count": 2,
"name":
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
"key": "cakes",
"doc_count": 2
]
,
.....
【讨论】:
@i_like_robots 我很好奇,你测试过我建议的解决方案了吗? 他决定把赏金留给自己,谢谢你的好回答! 最后,是的!我们最终能够花时间创建一个具有正确嵌套字段的新索引,但恐怕直到最近才出现。感谢您抽出宝贵时间回答我的问题,对于忽略任何 Stack Overflow 礼仪,我深表歉意! 现在不推荐使用“字符串”字段。检查elastic.co/guide/en/elasticsearch/reference/current/… 是否使用文本/关键字组合字段。以上是关于如何获得具有多个字段的 Elasticsearch 聚合的主要内容,如果未能解决你的问题,请参考以下文章