# Diversified Sampler Aggregation

原文链接 : [https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-diversified-sampler-aggregation.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-diversified-sampler-aggregation.html)

译文链接 : [http://www.apache.wiki/display/Elasticsearch](http://www.apache.wiki/display/Elasticsearch)（修改该链接为 **ApacheCN** 对应的译文链接）

贡献者 : @于永超，[ApacheCN](/display/~apachecn)，[Apache中文网](/display/~apachechina)

## Significant Terms Aggregation

在集合中返回有趣或不寻常的术语的聚合。

这个功能是实验性的，可以在未来的版本中完全改变或删除。 Elastic 将采取最大的努力来解决任何问题,但实验功能不受SLA官方GA特性的支持。

像“sampler”聚合一样，这是一个过滤聚合，用于将任何子聚合的处理限制为最高评分文档的样本。diversified_sampler聚合增加了限制共享一个值的匹配数量的能力，例如“author”。

任何好的市场研究人员都会告诉你，在使用数据样本时，重要的是样本表示健康的意见，而不是任何单一的声音。 聚合和采样同样如此，通过这些多样化设置可以提供一种方法来消除您内容中的偏见（人口过多的地理位置，时间轴上的大量峰值或过多的垃圾邮件发送者）。

## Example use cases:

*   将分析的重点放在高度相关性匹配上,而不是低质量的长尾词的匹配上
*   通过确保来自不同来源的内容的公平表示来消除分析中的偏见
*   Reducing the running cost of aggregations that can produce useful results using only samples e.g. `significant_terms`

`field或script设置的选择用于提供用于重复数据删除的值，而max_docs_per_value设置控制在任何共享一个公共值的shard上所收集的文档的最大数量。max_docs_per_value的默认设置为1`

如果字段或脚本的选择为单个文档生成多个值，则聚合将抛出错误（由于效率问题，不支持使用多值字段的重复数据删除）。

例子：

我们可能会想看看哪些标签在StackOverflow论坛上有很强的关联，但忽略了一些多数用户的拼写错误， 他们倾向把#Kibana误拼写为#Cabana。

```
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": 1000,  ＃1
            "keywords": { ＃2
                "doc_count": 1000,
                "buckets": [
                    {
                        "key": "kibana",
                        "doc_count": 150,
                        "score": 2.213,
                        "bg_count": 200
                    }
                ]
            }
        }
    }
}
```

＃1 因为我们从5个碎片的索引中询问了最多200个文件，所以共采集了1000份文件。 因此，执行嵌套的significant_terms聚合的成本是有限的，而不是无限制的。

＃2 significant_terms聚合结果不会被任何一个作者的怪癖所扭曲，因为我们在我们的示例中要求从任何一个作者那里获得最多的一个帖子

### Scripted example:

在这种情况下，我们可能希望将字段值的组合多样化。我们可以使用一个script来产生一个标签字段中的多个值的散列，以确保我们没有由相同的重复标签组合组成的样本。

```
POST /stackoverflow/_search?size=0
{
    "query": {
        "query_string": {
            "query": "tags:kibana"
        }
    },
    "aggs": {
        "my_unbiased_sample": {
            "diversified_sampler": {
                "shard_size": 200,
                "max_docs_per_value" : 3,
                "script" : {
                    "lang": "painless",
                    "inline": "doc['tags'].values.hashCode()"
                }
            },
            "aggs": {
                "keywords": {
                    "significant_terms": {
                        "field": "tags",
                        "exclude": ["kibana"]
                    }
                }
            }
        }
    }
}
```

结果：

```
{
    ...
    "aggregations": {
        "my_unbiased_sample": {
            "doc_count": 1000,
            "keywords": {
                "doc_count": 1000,
                "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是一个可选参数，并限制每个选择de-duplicating值允许的文档数量。 默认设置为“1”。

### execution_hint

可选的execution_hint设置可以影响用于de-duplication的管理，每个选项在执行de-duplication时都会保持内存中的shard_size值，但是可以如下控制持有的值的类型：

*   直接保存字段值(map)
*   根据Lucene索引(global_ordinals)确定字段的序名
*   保持字段值的哈希值 - 具有哈希冲突的可能性（bytes_hash）

默认设置是使用global_ordinals，如果该信息可以从Lucene索引中获得，并返回到map。在某些情况下，bytes_hash设置可能会更快一些，但由于哈希冲突的可能性，引入了de-duplication逻辑中的错误肯定的可能性。 请注意，Elasticsearch将忽略执行提示的选择，如果不适用，并且这些提示没有向后兼容性保证。

### Limitations

#### Cannot be nested under `breadth_first` aggregations

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

#### Limited de-dup logic.

de-duplication逻辑只适用于shard级别，因此不适用于across shards.

#### No specialized syntax for geo/date fields

目前用于定义多样化值的语法由field或script的选择来定义－没有添加语法糖来表达地理或日期单位，如“7d”（7天）。这种支持可能会在稍后的版本中添加，用户现在需要使用script创建这些类型的值。