Elasticsearch聚合多面导航,按组排除facets

use*_*478 5 facet elasticsearch elasticsearch-aggregation

我是ES的新手,并且一直在尝试以与大多数大型电子商务商店相同的方式实现分面导航.

我的部分产品映射如下所示:

'name' => [
    'type' => 'string',
    'analyzer' => 'english_analyzer',
],
'range' => [
    'type' => 'string',
    'analyzer' => 'english_analyzer',
],
'filters' => [
    'type' => 'nested',
    'properties' => [
        'name' => [
            'type' => 'string',
            'index' => 'not_analyzed',
        ],
        'values' => [
            'type' => 'object',
            'properties' => [
                'name' => [
                    'type' => 'string',
                    'index' => 'not_analyzed',
                ]
            ]
        ]
    ]
],
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我将facets作为嵌套对象存储在"filters"中.

在我的搜索查询中,我可以将此聚合添加到我的查询中:

'aggs' => [
    'facets' => [
        'nested' => ['path' => 'filters'],
        'aggs' => [
            'filters' => [
                'terms' => [
                    'field' => 'filters.name', //facet group name
                    'size' => 0
                ],
                'aggs' => [
                    'id' => [
                        'terms' => [
                            'field' => 'filters.id' //facet group ID
                        ]
                    ],
                    'values' => [
                        'terms' => [
                            'field' => 'filters.values.name', //facet name
                            'size' => 0
                        ],
                        'aggs' => [
                            'id' => [
                                'terms' => [
                                    'field' => 'filters.values.id' //facet id
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
]
Run Code Online (Sandbox Code Playgroud)

这给了我一个很好的清单,可以在我的导航中加入.我可以通过两种方式将选定的构面应用于我的文档结果:使用"后置过滤器"或"过滤后的查询"

后过滤器在查询后应用聚合,因此无论用户选择了哪些方面,都会为我提供文档计数.相比之下,过滤查询基于所选方面计算方面计数,但是它隐藏了没有匹配文档的方面.

我需要做的 - 以及大多数大型电子商务商店所做的 - 是2的混合.我希望方面计数基于所选择的内容但忽略同一组内的任何方面.

如果我有这些方面:

颜色:

  • 红色(1)
  • 蓝色(2)
  • 绿色(3)

品牌:

  • 奥迪(1)
  • 福特(2)
  • 宝马(3)

如果有人选择蓝色,红色和绿色的计数应保持相同,但会影响品牌的数量.

我在Stack Overflow上发现了一个类似的问题: ElasticSearch聚合:每个聚合排除一个过滤器

从我可以收集的内容中,我需要提供一个预定义的facet列表(来自我的关系数据库)并将它们添加到我的聚合中.所以我有一个我的facet组的手动列表,然后我为每个组添加了一个过滤器桶(https://www.elastic.co/guide/en/elasticsearch/guide/current/_filter_bucket.html).在过滤器中,我需要添加一个bool查询,其中包含我为每个构面组包含的所有用户选择的构面,而忽略了属于该组的任何构面.

所以现在我有一个庞大的聚合列表,由他们的facet组分组/分组,每个聚合都有一个包含bool查询的过滤器,可能有十几个选定的字段.现在查询是如此之大,如果我在这里发布它可能不适合在一个页面上!

这对我而言似乎是对我的查询的一个疯狂的补充,考虑到我以前必须做的几乎是我需要的.这是我能实现这一目标的唯一途径吗?

非常感谢任何帮助,我希望我的问题足够清楚.