Reo*_*kot 14 aggregate facet elasticsearch
在我们的一个新的项目,我们在这篇文章的启发http://project-a.github.io/on-site-search-design-patterns-for-e-commerce/#generic-faceted-search做我们的"facet"结构.虽然我已经在文章描述的范围内使用它,但是在选择方面时我遇到了让它工作的问题.我希望有人能给出一些可以尝试的提示,所以我不必再将所有聚合重做为单独的聚合计算.
问题基本上是我们使用单个聚合一次计算所有"方面",但是当我添加过滤器(fx.检查品牌名称)时,它会在返回聚合时"删除"所有其他品牌.我基本上想要的是它在计算其他方面时应该使用该品牌作为过滤器,但在计算品牌聚合时则不然.这是必要的,因此用户可以选择多个品牌.
看看https://www.contorion.de/search/Metabo_Fein/ou1-ou2?q=Winkelschleifer&c=bovy(这是上面文章中描述的网站),我选择了"Metabo"和"Fein"制造商( Hersteller),并展示了Hersteller菜单,它显示了所有制造商,而不仅仅是所选择的制造商.所以我知道它有可能以某种方式,我希望有一个关于如何编写聚合/过滤器的提示,所以我得到了"正确的电子商务方面行为".
在ES中的产品我有以下结构:(与原始文章相同,但在命名时使用"C#"ified)
"attributeStrings": [
{
"facetName": "Property",
"facetValue": "Organic"
},
{
"facetName": "Property",
"facetValue": "Without parfume"
},
{
"facetName": "Brand",
"facetValue": "Adidas"
}
]
Run Code Online (Sandbox Code Playgroud)
所以上面的产品有2个属性/方面组 - 属性有2个值(有机,没有香水)和品牌有1个值(阿迪达斯).没有任何过滤器,我从以下查询计算聚合:
"aggs": {
"agg_attr_strings_filter": {
"filter": {},
"aggs": {
"agg_attr_strings": {
"nested": {
"path": "attributeStrings"
},
"aggs": {
"attr_name": {
"terms": {
"field": "attributeStrings.facetName"
},
"aggs": {
"attr_value": {
"terms": {
"field": "attributeStrings.facetValue",
"size": 1000,
"order": [
{
"_term": "asc"
}
]
} } } } } } } }
Run Code Online (Sandbox Code Playgroud)
现在,如果我选择属性"有机"和品牌"阿迪达斯"我构建相同的聚合,但使用过滤器来应用这两个约束(这是有点出错......):
"aggs": {
"agg_attr_strings_filter": {
"filter": {
"bool": {
"filter": [
{
"nested": {
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Property"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Organic"
]
}
}
]
}
},
"path": "attributeStrings"
}
},
{
"nested": {
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Brand"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Adidas"
]
}
}
]
}
},
"path": "attributeStrings"
}
}
]
}
},
"aggs": {
"agg_attr_strings": {
"nested": {
"path": "attributeStrings"
},
"aggs": {
"attr_name": {
"terms": {
"field": "attributeStrings.facetName",
},
"aggs": {
"attr_value": {
"terms": {
"field": "attributeStrings.facetValue",
"size": 1000,
"order": [
{
"_term": "asc"
}
]
} } } } } } } }
Run Code Online (Sandbox Code Playgroud)
我可以看到这个模型的唯一方法是计算每个选定方面的聚合,并以某种方式合并结果.但它看起来非常复杂,有点像文章中所描述的那样使模型失败,所以我希望有一个更清晰的解决方案,有人可以提供一些尝试.
hak*_*kaa 19
我可以看到这个模型的唯一方法是计算每个选定方面的聚合,并以某种方式合并结果.
这是完全正确的.如果您选择了一个方面(例如品牌)而不是使用全球品牌过滤器,如果您还想获取其他品牌进行多选.您可以执行的操作是应用所选构面上的所有其他滤镜以及未选定构面上的所有 滤镜.作为结果,您将为选定的过滤器n+1分别进行聚合n- 第一个用于所有方面,其余用于选定方面.
在您的情况下,查询可能如下所示:
{
"aggs": {
"agg_attr_strings_filter": {
"filter": {
"bool": {
"filter": [
{
"nested": {
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Property"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Organic"
]
}
}
]
}
},
"path": "attributeStrings"
}
},
{
"nested": {
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Brand"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Adidas"
]
}
}
]
}
},
"path": "attributeStrings"
}
}
]
}
},
"aggs": {
"agg_attr_strings": {
"nested": {
"path": "attributeStrings"
},
"aggs": {
"attr_name": {
"terms": {
"field": "attributeStrings.facetName"
},
"aggs": {
"attr_value": {
"terms": {
"field": "attributeStrings.facetValue",
"size": 1000,
"order": [
{
"_term": "asc"
}
]
}
}
}
}
}
}
}
},
"special_agg_property": {
"filter": {
"nested": {
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Brand"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Adidas"
]
}
}
]
}
},
"path": "attributeStrings"
}
},
"aggs": {
"special_agg_property": {
"nested": {
"path": "attributeStrings"
},
"aggs": {
"agg_filtered_special": {
"filter": {
"query": {
"match": {
"attributeStrings.facetName": "Property"
}
}
},
"aggs": {
"facet_value": {
"terms": {
"size": 1000,
"field": "attributeStrings.facetValue"
}
}
}
}
}
}
}
},
"special_agg_brand": {
"filter": {
"nested": {
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Property"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Organic"
]
}
}
]
}
},
"path": "attributeStrings"
}
},
"aggs": {
"special_agg_brand": {
"nested": {
"path": "attributeStrings"
},
"aggs": {
"agg_filtered_special": {
"filter": {
"query": {
"match": {
"attributeStrings.facetName": "Brand"
}
}
},
"aggs": {
"facet_value": {
"terms": {
"size": 1000,
"field": "attributeStrings.facetValue"
}
}
}
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个查询看起来超级大而可怕,但生成这样的查询可以用几十行代码完成.解析查询结果时,需要首先解析一般聚合(使用所有过滤器的聚合)和特殊构面聚合之后.从上面的示例,从第一解析结果agg_attr_strings_filter,但这些结果也将包含聚集值的品牌和财产应该由聚合值从被覆盖special_agg_property,并special_agg_brand
另外,这个查询是有效的,因为Elasticsearch确实做好缓存单独的过滤条款,从而适用相同的筛选器在查询的不同部分应该便宜.
但它看起来非常复杂,有点像文章中所描述的那样使模型失败,所以我希望有一个更清晰的解决方案,有人可以提供一些尝试.
实际上,您无需将不同的过滤器应用于不同的方面,同时具有不同的查询过滤器.如果您需要支持"正确的电子商务方面行为",您将有复杂的查询:)
免责声明:我是上述文章的合着者.
问题来自以下事实:您在聚合的内部Property和Organic 内部添加了一个过滤器,因此,选择的方面越多,约束条件越多。在那篇文章中,filter他们实际上使用的是a post_filter,两个名称直到最近都被允许使用,但是由于造成歧义而filter 被删除。
您需要做的是将过滤器移到聚合之外的post_filter部分中,以使结果能够被选择的任何构面正确地过滤掉,但您的所有构面仍将在整个文档集中正确计算。
{
"post_filter": {
"bool": {
"filter": [
{
"nested": {
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Property"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Organic"
]
}
}
]
}
},
"path": "attributeStrings"
}
},
{
"nested": {
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Brand"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Adidas"
]
}
}
]
}
},
"path": "attributeStrings"
}
}
]
}
},
"aggs": {
"agg_attr_strings_full": {
"nested": {
"path": "attributeStrings"
},
"aggs": {
"attr_name": {
"terms": {
"field": "attributeStrings.facetName"
},
"aggs": {
"attr_value": {
"terms": {
"field": "attributeStrings.facetValue",
"size": 1000,
"order": [
{
"_term": "asc"
}
]
}
}
}
}
}
},
"agg_attr_strings_filtered": {
"filter": {
"bool": {
"filter": [
{
"nested": {
"path": "attributeStrings",
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Property"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Organic"
]
}
}
]
}
}
}
},
{
"nested": {
"path": "attributeStrings",
"query": {
"bool": {
"filter": [
{
"term": {
"attributeStrings.facetName": {
"value": "Brand"
}
}
},
{
"terms": {
"attributeStrings.facetValue": [
"Adidas"
]
}
}
]
}
}
}
}
]
}
},
"aggs": {
"nested": {
"path": "attributeStrings"
},
"aggs": {
"attr_name": {
"terms": {
"field": "attributeStrings.facetName"
},
"aggs": {
"attr_value": {
"terms": {
"field": "attributeStrings.facetValue",
"size": 1000,
"order": [
{
"_term": "asc"
}
]
}
}
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3230 次 |
| 最近记录: |