首页 > 解决方案 > 如何处理分面过滤和相应的聚合计数?

问题描述

祝大家有美好的一天。问题涉及分面搜索。

假设有 2 个过滤器:

2.1 类别 货运 (1765) 汽车 (1566) 任何其他 (8675)

2.2 颜色 红色 (5689) 绿色 (156) 蓝色 (3599) 黄色 (2562)

正如我们在每个过滤器前面看到的那样,它表明有多少元素单独存储在弹性中。在“运费”前面打勾。

现在的行为:

2.1 类别 货运 (1765) 汽车 (0) 更多 (0)

2.2 颜色 Red(红色货号) Green(绿色货号) Blue(蓝色货号) Yellow(黄色货号)

你需要这种行为:

2.1 类别 货运 (1765) 汽车 (1566) 任何其他 (8675)

2.2 颜色 Red(红色货号) Green(绿色货号) Blue(蓝色货号) Yellow(黄色货号)

也就是说,特定字段上的过滤器不会影响其聚合,但会影响所有其他字段。如何实现优化?现在实现了对 x 请求弹性,并且 x 等于过滤器的数量

最好的祝愿

标签: elasticsearch

解决方案


假设初始查询是match_all,查询

2.1 类别 货运 (1765) 汽车 (1566) 任何其他 (8675)

2.2 颜色 红色 (5689) 绿色 (156) 蓝色 (3599) 黄色 (2562)

将会:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "CATEGORIES": {
      "terms": {
        "field": "category"
      }
    },
    "COLORS": {
      "terms": {
        "field": "color"
      }
    }
  }
}

何时Freight选择预期的内容逐步解释如下:

1.过滤记录

这可以使用category字段上的术语查询来实现。现在,如果在聚合之前应用此查询,则会导致问题中提到的问题。刻面将CATEGORIES有计数Frieght,其他计数将为零。虽然COLORS方面会有预期的计数。为了解决这个问题,我们可以使用post_filter。这将确保在准备聚合后完成对记录的过滤。

这就是它的工作方式:

第 1 步: match_all(原始查询)

第 2 步:准备聚合

第 3 步:应用过滤器(预期的搜索结果)

通过以上我们将获得正确的过滤结果和预期CATEGORIES的计数方面,但计数COLORS仍然相同,根据方面的选择预期会减少CATEGORIES。下一步将解决此问题。

2.其他方面的计数将相应更改

为了解决这个问题,我们将使用过滤器聚合以及实际聚合。我们将在应该影响计数的每个剩余聚合中应用 post_filter,即除了CATEGORIES在我们的例子中的所有聚合之外的所有聚合COLORS

结合以上两个步骤,查询将是:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "CATEGORIES": {
      "terms": {
        "field": "category"
      }
    },
    "COLORS": {
      "filter": {
        "terms": {
          "category": [
            "Freight"
          ]
        },
        "aggs": {
          "COLORS": {
            "terms": {
              "field": "color"
            }
          }
        }
      }
    },
    "post_filter": {
      "terms": {
        "category": [
          "Freight"
        ]
      }
    }
  }
}

推荐阅读