如果在弹性搜索中选择阵列字段的另一个聚合选项,如何获取将添加的文档的数量

Ste*_*yer 5 search elasticsearch

假设我们有四个带有tags字段的文档.它可以包含多个字符串,比方说foo,barbaz.

docA.tags = ['foo']
docB.tags = ['bar']
docC.tags = ['foo', 'bar']
docD.tags = ['foo', 'baz']
Run Code Online (Sandbox Code Playgroud)

我使用聚合查询文档,因此我获得了四个文档和三个桶的列表,其中包含与特定标记匹配的计数.

buckets = [
  {key: 'bar', doc_count: 2}, // docB, docC
  {key: 'foo', doc_count: 3}, // docA, docC, docD
  {key: 'baz', doc_count: 1}  // docD
]
Run Code Online (Sandbox Code Playgroud)

如果我现在运行另一个查询,并添加这些标签中的一个-让说foo-作为一个条件过滤器来查询,我只得到了文档(docA,docC,docD有此标记).这就是我想要的.

但我还得到了另一个可能的聚合列表,其中包含更新的计数.

buckets = [
  {key: 'bar', doc_count: 1}, // docC
  {key: 'baz', doc_count: 1}, // docD
]
Run Code Online (Sandbox Code Playgroud)

但这些计数与发生的事情并不完全一致.它们反映了与两个标签匹配的文档数,即我在第一个位置选择的标签(foo)和一个标签(barbaz).

但是,如果我然后选择第二个标签 - 比方说baz- 我得到的文件已被标记为fooOR baz.那是因为我使用terms过滤器.

所以我真正想要的是这个

buckets = [
  {key: 'bar', doc_count: 1}, //docB
  {key: 'baz', doc_count: 0},
]
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现计数合适.如果我选择第二个标记,它们应该反映将添加的文档数.这方面的一个例子是在这里.

我已经尝试过使用post_filter但总是给我第一个结果.比min_doc_countaggs的标志,但这只显示了导致的组合count=0.

我有一个解决方案,但对我来说似乎很复杂.为此,我将不得不为每个聚合运行另一个请求,其中我反转过滤条件.因此,在上面的示例中,我必须对没有标记foo的所有文档进行查询,并匹配查询的其余部分.聚合结果正是我所需要的.

Pet*_*ses 0

听起来您正在尝试为方面/聚合做一些有点不典型的事情。

(但是,它并不是无效的......了解您的选择的大小将如何通过应用过滤器改变是很有意义的)

我认为你要求的是:

  1. 显示以下结果:查询 过滤
  2. 显示以下项的术语聚合计数: QUERY NOT FILTER

在此输入图像描述

您提到您正在执行后续计数请求?您应该能够在主搜索请求中构建此聚合请求。

从结构上来说是:

  • 匹配:( QUERY ) 或 match_all
  • 聚合:
    • 过滤器:{不是:(过滤器)}
      • 聚合:{ 术语:... }
  • 后过滤器:(过滤器

post_filter在计算聚合后执行(但仍应用于搜索结果),因此您的结果将是您所期望的。

聚合仅在搜索查询的范围内起作用。(后置滤波器尚未应用。)

在术语聚合计算计数之前,过滤器聚合会从搜索查询结果中排除所有与FILTER匹配的文档。

(给你上面显示的维恩的左外边缘,但只是为了计数)