多元化采样器聚合编辑

sampler 聚合类似,这是一种过滤聚合,用于将任何子聚合的处理限制为对得分最高的文档的样本。 diversified_sampler 聚合增加了限制共享共同值(例如“作者”)的匹配项数量的能力。

任何优秀的市场研究人员都会告诉你,在处理数据样本时,重要的是样本代表了各种各样的意见,而不是被任何单一的声音所扭曲。对于聚合和采样来说也是如此,使用这些多样化设置进行采样可以提供一种方法来消除内容中的偏差(人口过多的地理位置、时间线上的巨大峰值或过于活跃的论坛垃圾邮件发送者)。

示例用例

  • 将分析的重点缩小到高相关性匹配,而不是潜在的非常长的低质量匹配尾部
  • 通过确保来自不同来源的内容的公平代表来消除分析中的偏差
  • 降低仅使用样本即可产生有用结果的聚合的运行成本,例如 significant_terms

field 设置用于提供用于去重的值,而 max_docs_per_value 设置控制在任何一个共享共同值的碎片上收集的最大文档数量。 max_docs_per_value 的默认设置为 1。

如果 field 为单个文档生成多个值,则聚合将抛出错误(由于效率问题,不支持使用多值字段进行去重)。

示例

我们可能想看看哪些标签与 StackOverflow 论坛帖子上的 #elasticsearch 密切相关,但忽略了一些多产用户的误用 #Kibana 为 #Cabana 的影响。

response = client.search(
  index: 'stackoverflow',
  size: 0,
  body: {
    query: {
      query_string: {
        query: 'tags:elasticsearch'
      }
    },
    aggregations: {
      my_unbiased_sample: {
        diversified_sampler: {
          shard_size: 200,
          field: 'author'
        },
        aggregations: {
          keywords: {
            significant_terms: {
              field: 'tags',
              exclude: [
                'elasticsearch'
              ]
            }
          }
        }
      }
    }
  }
)
puts response
POST /stackoverflow/_search?size=0
{
  "query": {
    "query_string": {
      "query": "tags:elasticsearch"
    }
  },
  "aggs": {
    "my_unbiased_sample": {
      "diversified_sampler": {
        "shard_size": 200,
        "field": "author"
      },
      "aggs": {
        "keywords": {
          "significant_terms": {
            "field": "tags",
            "exclude": [ "elasticsearch" ]
          }
        }
      }
    }
  }
}

响应

{
  ...
  "aggregations": {
    "my_unbiased_sample": {
      "doc_count": 151,           
      "keywords": {               
        "doc_count": 151,
        "bg_count": 650,
        "buckets": [
          {
            "key": "kibana",
            "doc_count": 150,
            "score": 2.213,
            "bg_count": 200
          }
        ]
      }
    }
  }
}

总共采样了 151 个文档。

由于我们要求样本中每个作者最多只有一篇文章,因此 significant_terms 聚合的结果不会因任何单个作者的怪癖而扭曲。

脚本示例编辑

在这种情况下,我们可能希望对字段值的组合进行多样化。我们可以使用 运行时字段 来生成标签字段中多个值的哈希值,以确保我们没有由相同的重复标签组合组成的样本。

response = client.search(
  index: 'stackoverflow',
  size: 0,
  body: {
    query: {
      query_string: {
        query: 'tags:kibana'
      }
    },
    runtime_mappings: {
      'tags.hash' => {
        type: 'long',
        script: "emit(doc['tags'].hashCode())"
      }
    },
    aggregations: {
      my_unbiased_sample: {
        diversified_sampler: {
          shard_size: 200,
          max_docs_per_value: 3,
          field: 'tags.hash'
        },
        aggregations: {
          keywords: {
            significant_terms: {
              field: 'tags',
              exclude: [
                'kibana'
              ]
            }
          }
        }
      }
    }
  }
)
puts response
POST /stackoverflow/_search?size=0
{
  "query": {
    "query_string": {
      "query": "tags:kibana"
    }
  },
  "runtime_mappings": {
    "tags.hash": {
      "type": "long",
      "script": "emit(doc['tags'].hashCode())"
    }
  },
  "aggs": {
    "my_unbiased_sample": {
      "diversified_sampler": {
        "shard_size": 200,
        "max_docs_per_value": 3,
        "field": "tags.hash"
      },
      "aggs": {
        "keywords": {
          "significant_terms": {
            "field": "tags",
            "exclude": [ "kibana" ]
          }
        }
      }
    }
  }
}

响应

{
  ...
  "aggregations": {
    "my_unbiased_sample": {
      "doc_count": 6,
      "keywords": {
        "doc_count": 6,
        "bg_count": 650,
        "buckets": [
          {
            "key": "logstash",
            "doc_count": 3,
            "score": 2.213,
            "bg_count": 50
          },
          {
            "key": "elasticsearch",
            "doc_count": 3,
            "score": 1.34,
            "bg_count": 200
          }
        ]
      }
    }
  }
}

shard_size编辑

shard_size 参数限制了在每个碎片上处理的样本中收集的得分最高的文档数量。默认值为 100。

max_docs_per_value编辑

max_docs_per_value 是一个可选参数,它限制了每个去重值选择允许的文档数量。默认设置为“1”。

execution_hint编辑

可选的 execution_hint 设置可以影响用于去重的值的管理。每个选项在执行去重时将在内存中保存最多 shard_size 个值,但可以控制保存的值类型,如下所示

  • 直接保存字段值 (map)
  • 保存由 Lucene 索引确定的字段的序数 (global_ordinals)
  • 保存字段值的哈希值 - 可能会发生哈希冲突 (bytes_hash)

默认设置为使用 global_ordinals(如果此信息可从 Lucene 索引获得),否则恢复为 map。在某些情况下,bytes_hash 设置可能更快,但由于可能发生哈希冲突,它会引入去重逻辑中出现假阳性的可能性。请注意,如果执行提示不适用,Elasticsearch 将忽略执行提示的选择,并且这些提示没有向后兼容性保证。

限制编辑

不能嵌套在 breadth_first 聚合下编辑

作为一种基于质量的过滤器,diversified_sampler 聚合需要访问为每个文档生成的关联分数。因此,它不能嵌套在 terms 聚合下,该聚合的 collect_mode 从默认的 depth_first 模式切换到 breadth_first,因为这会丢弃分数。在这种情况下,将抛出错误。

有限的去重逻辑。编辑

去重逻辑仅在碎片级别应用,因此不会跨碎片应用。

没有针对地理/日期字段的专门语法编辑

目前,定义多样化值的语法由 fieldscript 的选择定义 - 没有为表达地理或日期单位(例如“7d”(7 天))添加额外的语法糖。此支持可能会在以后的版本中添加,用户目前必须使用脚本创建这些类型的值。