多様なサンプラー集約
sampler
集約と同様に、これはフィルタリング集約であり、サブ集約の処理を上位スコアのドキュメントのサンプルに制限するために使用されます。diversified_sampler
集約は、共通の値(例えば「著者」)を共有する一致の数を制限する機能を追加します。
優れた市場調査者は、データのサンプルを扱う際には、そのサンプルが特定の声によって偏ることなく、健全な意見の多様性を表すことが重要であると教えてくれます。集約とサンプリングでも同様で、これらの多様化設定を使用することで、コンテンツのバイアスを取り除く方法を提供できます(過剰に人口が集中した地理、タイムラインの大きなスパイク、または過剰に活動するフォーラムのスパム投稿者など)。
使用例:
- 分析の焦点を高い関連性の一致に絞り、低品質の一致の非常に長い尾を避ける
- 異なるソースからのコンテンツの公正な表現を確保することで、分析からのバイアスを取り除く
- サンプルのみを使用して有用な結果を生成できる集約の実行コストを削減する(例:
significant_terms
)
field
設定は、重複排除に使用される値を提供するために使用され、max_docs_per_value
設定は、共通の値を共有する任意のシャードで収集されるドキュメントの最大数を制御します。max_docs_per_value
のデフォルト設定は 1 です。
field
が単一のドキュメントに対して複数の値を生成する場合、集約はエラーをスローします(効率の懸念から、複数値フィールドを使用した重複排除はサポートされていません)。
例:
StackOverflow フォーラムの投稿で #elasticsearch
に強く関連付けられているタグを確認したいが、#Kibana を #Cabana と誤って綴る傾向のある一部の prolific ユーザーの影響を無視したい場合。
Python
resp = client.search(
index="stackoverflow",
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"
]
}
}
}
}
},
)
print(resp)
Ruby
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
Js
const response = await client.search({
index: "stackoverflow",
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"],
},
},
},
},
},
});
console.log(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のドキュメントがサンプリングされました。 | |
重要な_用語集約の結果は、サンプル内の任意の著者からの最大1つの投稿を要求したため、特定の著者の癖によって偏っていません。 |
スクリプト例
このシナリオでは、フィールド値の組み合わせで多様化を図りたいと考えています。タグフィールド内の複数の値のハッシュを生成するために ランタイムフィールド を使用して、同じ繰り返しのタグの組み合わせからなるサンプルを持たないようにします。
Python
resp = client.search(
index="stackoverflow",
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"
]
}
}
}
}
},
)
print(resp)
Ruby
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
Js
const response = await client.search({
index: "stackoverflow",
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"],
},
},
},
},
},
});
console.log(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
)
デフォルト設定は、Lucene インデックスからこの情報が利用可能な場合は global_ordinals
を使用し、そうでない場合は map
に戻ります。bytes_hash
設定は、いくつかのケースでより高速である可能性がありますが、ハッシュ衝突の可能性により重複排除ロジックにおいて偽陽性の可能性を導入します。Elasticsearch は、適用できない場合は実行ヒントの選択を無視し、これらのヒントに対して後方互換性の保証はありませんのでご注意ください。
制限事項
幅優先集約の下にネストできません
品質ベースのフィルターである多様化サンプラー集約は、各ドキュメントに対して生成される関連スコアにアクセスする必要があります。したがって、terms
集約の下にネストすることはできません。collect_mode
がデフォルトの depth_first
モードから breadth_first
に切り替わると、スコアが破棄されるためです。この状況ではエラーがスローされます。
制限された重複排除ロジック
重複排除ロジックはシャードレベルでのみ適用されるため、シャード間では適用されません。
地理/日付フィールド用の特別な構文はありません
現在、多様化値を定義するための構文は、field
または script
の選択によって定義されています - 「7d」(7日)などの地理または日付単位を表現するための追加の構文的な糖衣はありません。このサポートは後のリリースで追加される可能性があり、ユーザーは現在、スクリプトを使用してこの種の値を作成する必要があります。