我一直在使用elasticsearch查询和过滤一段时间但以前从未使用过聚合。我们可以使用我们的查询来定义聚合的想法对我来说似乎相当惊人,但我想要了解如何正确地做到这一点,这样我就不会犯任何错误。目前我的所有搜索查询都是这样设计的:
{
"query": {
},
"filter": {
},
"from": 0,
"size": 60
}
现在,当我添加一些聚合桶时,结构变为:
{
"aggs": {
"all_colors": {
"terms": {
"field": "color.name"
}
},
"all_brands": {
"terms": {
"field": "brand_slug"
}
},
"all_sizes": {
"terms": {
"field": "sizes"
}
}
},
"query": {
},
"filter": {
},
"from": 0,
"size": 60
}
然而,无论我在过滤器中提供什么信息,聚合的结果总是相同的。
现在,当我将查询结构更改为类似内容时,它开始显示不同的结果:
{
"aggs": {
"all_colors": {
"terms": {
"field": "color.name"
}
},
"all_brands": {
"terms": {
"field": "brand_slug"
}
},
"all_sizes": {
"terms": {
"field": "sizes"
}
}
},
"query": {
"filtered": {
"query": {
},
"filter": {
}
}
},
"from": 0,
"size": 60
}
这是否意味着我必须将搜索查询的结构更改为这种新的过滤类型的结构?还有其他解决方法可以让我在不需要改变那么多代码的情况下实现预期的结果吗?
另外,我观察到的另一件事是,如果我的brand_slug
字段包含多个关键字,例如“peter england”,那么这两个字段都会在不同的存储桶中返回,如下所示:
{
"buckets": [
{
"key": "england",
"doc_count": 368
},
{
"key": "peter",
"doc_count": 368
}
]
}
如何确保这两者最终都在同一个桶中:
{
"buckets": [
{
"key": "peter england",
"doc_count": 368
}
]
}
更新:我可以通过不同的方式对品牌,颜色和尺寸进行索引来完成第二部分:
"sizes": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
答案 0 :(得分:4)
你注意到的是设计。请看my answer关于SO的类似问题。基本上,聚合和过滤器部分的输入是查询部分的输出。 Filtered Query正如您所建议的那样,这是实现您想要的结果的最佳方式。还有另一种方式。您可以使用Filter Aggregation。然后你不需要更改你的查询和过滤器部分,只需复制聚合部分内的过滤器部分,但在我看来,这通常是一种过度杀伤和违反DRY principle。