应用聚合后过滤掉弹性搜索中的术语聚合桶
Posted
技术标签:
【中文标题】应用聚合后过滤掉弹性搜索中的术语聚合桶【英文标题】:Filter out terms aggregation buckets in elasticsearch after applying aggregation 【发布时间】:2021-07-03 08:54:23 【问题描述】:以下是数据集的快照:
recordNo employeeId employeeStatus employeeAddr
1 employeeA Permanent
2 employeeA ABC
3 employeeB Contract
4 employeeB CDE
我想获取员工列表以及employeeStatus 和employeeAddr。
所以我在employeeId 上使用术语聚合,然后使用employeeStatus 和employeeAddr 的子聚合来获取这些详细信息。 下面的查询正确返回结果。
"aggregations":
"Employee":
"terms":
"field": "employeeID"
,
"aggregations":
"employeeStatus":
"terms": "field": "employeeStatus"
,
"employeeAddr":
"terms": "field": "employeeAddr"
现在我只想要永久身份的员工。所以我正在应用过滤器聚合。
"aggregations":
"filter_Employee_employeeID":
"filter":
"bool":
"must": [
"match":
"employeeStatus": "query": "Permanent"
]
,
"aggregations":
"Employee":
"terms":
"field": "employeeID"
,
"aggregations":
"employeeStatus":
"terms": "field": "employeeStatus"
,
"employeeAddr":
"terms": "field": "employeeAddr"
现在的问题是employeeAddr 聚合没有为employeeA 返回任何桶,因为在聚合完成之前记录2 被过滤掉了。
假设我无法修改数据集,我想通过单个弹性查询来达到结果,我该怎么做?
我检查了 Bucket Selector 管道聚合,但它仅适用于指标聚合。 有没有办法在应用聚合后过滤掉术语桶?
【问题讨论】:
您期望的搜索结果是什么? 我需要永久雇员的所有详细信息。因此,例如,预期的输出是应返回employeeA 存储桶,并且在子聚合中,应返回用于employeeStatus 的存储桶“Permanent”和用于employeeAddr 的存储桶“ABC”。目前在结果中,employeeAddr 下没有重新调整“ABC”存储桶,因为过滤器 agg 中的查询删除了数据集的记录 2。 【参考方案1】:如果我理解正确,即使您使用某种过滤器,您也希望保留聚合。为此,请尝试使用 post_filter 子句。
您可以查看文档here
该子句应用于聚合“外部”。使用您的示例,它应该如下所示:
"aggregations":
"filter_Employee_employeeID":
"aggregations":
"Employee":
"terms":
"field": "employeeID"
,
"aggregations":
"employeeStatus":
"terms":
"field": "employeeStatus"
,
"employeeAddr":
"terms":
"field": "employeeAddr"
,
"post_filter":
"bool":
"must": [
"match":
"employeeStatus":
"query": "Permanent"
]
【讨论】:
您好,Vitor,感谢您的意见。如果我正确理解了文档,post_filter 将过滤掉响应的“命中”部分中的结果。我需要对聚合结果应用过滤器,因为聚合结果经过处理以显示在客户端。上面我只粘贴了查询的 sn-p,但也有 Employee 下的子实体的子聚合和聚合桶的分页支持,所以我需要层次结构格式的过滤数据。以上是关于应用聚合后过滤掉弹性搜索中的术语聚合桶的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch 中的术语聚合返回单词而不是完整字段值的存储桶