Suggesters
提供されたテキストに基づいて、似たような用語を提案するためにサジェスターを使用します。
Python
resp = client.search(
index="my-index-000001",
query={
"match": {
"message": "tring out Elasticsearch"
}
},
suggest={
"my-suggestion": {
"text": "tring out Elasticsearch",
"term": {
"field": "message"
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'my-index-000001',
body: {
query: {
match: {
message: 'tring out Elasticsearch'
}
},
suggest: {
"my-suggestion": {
text: 'tring out Elasticsearch',
term: {
field: 'message'
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "my-index-000001",
query: {
match: {
message: "tring out Elasticsearch",
},
},
suggest: {
"my-suggestion": {
text: "tring out Elasticsearch",
term: {
field: "message",
},
},
},
});
console.log(response);
Console
POST my-index-000001/_search
{
"query" : {
"match": {
"message": "tring out Elasticsearch"
}
},
"suggest" : {
"my-suggestion" : {
"text" : "tring out Elasticsearch",
"term" : {
"field" : "message"
}
}
}
}
Request
サジェスト機能は、提供されたテキストに基づいて似たような用語を提案します。サジェストリクエスト部分は、_search
リクエストのクエリ部分と一緒に定義されます。クエリ部分が省略された場合、提案のみが返されます。
Examples
リクエストごとに複数の提案を指定できます。各提案は任意の名前で識別されます。以下の例では、2つの提案が要求されています。my-suggest-1
とmy-suggest-2
の両方の提案はterm
サジェスターを使用していますが、text
は異なります。
Python
resp = client.search(
suggest={
"my-suggest-1": {
"text": "tring out Elasticsearch",
"term": {
"field": "message"
}
},
"my-suggest-2": {
"text": "kmichy",
"term": {
"field": "user.id"
}
}
},
)
print(resp)
Ruby
response = client.search(
body: {
suggest: {
"my-suggest-1": {
text: 'tring out Elasticsearch',
term: {
field: 'message'
}
},
"my-suggest-2": {
text: 'kmichy',
term: {
field: 'user.id'
}
}
}
}
)
puts response
Js
const response = await client.search({
suggest: {
"my-suggest-1": {
text: "tring out Elasticsearch",
term: {
field: "message",
},
},
"my-suggest-2": {
text: "kmichy",
term: {
field: "user.id",
},
},
},
});
console.log(response);
Console
POST _search
{
"suggest": {
"my-suggest-1" : {
"text" : "tring out Elasticsearch",
"term" : {
"field" : "message"
}
},
"my-suggest-2" : {
"text" : "kmichy",
"term" : {
"field" : "user.id"
}
}
}
}
以下のサジェストレスポンスの例には、my-suggest-1
とmy-suggest-2
の提案レスポンスが含まれています。各提案部分にはエントリが含まれています。各エントリは実質的にサジェストテキストからのトークンであり、提案エントリテキスト、サジェストテキスト内の元の開始オフセットと長さ、および見つかった場合の任意の数のオプションが含まれています。
Console-Result
{
"_shards": ...
"hits": ...
"took": 2,
"timed_out": false,
"suggest": {
"my-suggest-1": [ {
"text": "tring",
"offset": 0,
"length": 5,
"options": [ {"text": "trying", "score": 0.8, "freq": 1 } ]
}, {
"text": "out",
"offset": 6,
"length": 3,
"options": []
}, {
"text": "elasticsearch",
"offset": 10,
"length": 13,
"options": []
} ],
"my-suggest-2": ...
}
}
各オプション配列には、提案されたテキスト、その文書頻度、および提案エントリテキストに対するスコアを含むオプションオブジェクトが含まれています。スコアの意味は使用されるサジェスターによって異なります。用語サジェスターのスコアは編集距離に基づいています。
Global suggest text
サジェストテキストの繰り返しを避けるために、グローバルテキストを定義することが可能です。以下の例では、サジェストテキストがグローバルに定義され、my-suggest-1
とmy-suggest-2
の提案に適用されます。
Php
$params = [
'body' => [
'suggest' => [
'text' => 'tring out Elasticsearch',
'my-suggest-1' => [
'term' => [
'field' => 'message',
],
],
'my-suggest-2' => [
'term' => [
'field' => 'user',
],
],
],
],
];
$response = $client->search($params);
Python
resp = client.search(
suggest={
"text": "tring out Elasticsearch",
"my-suggest-1": {
"term": {
"field": "message"
}
},
"my-suggest-2": {
"term": {
"field": "user"
}
}
},
)
print(resp)
Ruby
response = client.search(
body: {
suggest: {
text: 'tring out Elasticsearch',
"my-suggest-1": {
term: {
field: 'message'
}
},
"my-suggest-2": {
term: {
field: 'user'
}
}
}
}
)
puts response
Go
res, err := es.Search(
es.Search.WithBody(strings.NewReader(`{
"suggest": {
"text": "tring out Elasticsearch",
"my-suggest-1": {
"term": {
"field": "message"
}
},
"my-suggest-2": {
"term": {
"field": "user"
}
}
}
}`)),
es.Search.WithPretty(),
)
fmt.Println(res, err)
Js
const response = await client.search({
suggest: {
text: "tring out Elasticsearch",
"my-suggest-1": {
term: {
field: "message",
},
},
"my-suggest-2": {
term: {
field: "user",
},
},
},
});
console.log(response);
Console
POST _search
{
"suggest": {
"text" : "tring out Elasticsearch",
"my-suggest-1" : {
"term" : {
"field" : "message"
}
},
"my-suggest-2" : {
"term" : {
"field" : "user"
}
}
}
}
上記の例では、サジェストテキストも提案特有のオプションとして指定できます。提案レベルで指定されたサジェストテキストは、グローバルレベルのサジェストテキストを上書きします。
Term suggester
#### Common suggest options:
| | |
| --- | --- |
| `````text````` | サジェストテキスト。サジェストテキストは、グローバルまたは提案ごとに設定する必要がある必須オプションです。 |
| `````field````` | 候補提案を取得するフィールド。これはグローバルまたは提案ごとに設定する必要がある必須オプションです。 |
| `````analyzer````` | サジェストテキストを分析するためのアナライザー。デフォルトはサジェストフィールドの検索アナライザーです。 |
| `````size````` | サジェストテキストトークンごとに返される最大修正数。 |
| `````sort````` | サジェストテキスト用語ごとに提案がどのようにソートされるべきかを定義します。2つの可能な値:<br>- `````score`````: スコアで最初にソートし、次に文書頻度、最後に用語自体をソートします。<br>- `````frequency`````: 文書頻度で最初にソートし、次に類似性スコア、最後に用語自体をソートします。 |
| `````suggest_mode````` | サジェストモードは、どの提案が含まれるか、またはどのサジェストテキスト用語に対して提案が行われるべきかを制御します。指定できる3つの可能な値:
- `````missing`````: インデックスに存在しないサジェストテキスト用語の提案のみを提供します(デフォルト)。
- `````popular`````: 元のサジェストテキスト用語よりも多くの文書に出現する提案のみを提案します。
- `````always`````: サジェストテキスト内の用語に基づいて一致する提案を提案します。
#### Other term suggest options:
| | |
| --- | --- |
| `````max_edits````` | 提案として考慮されるために候補提案が持つことができる最大編集距離。1と2の間の値のみです。他の値は不正なリクエストエラーを引き起こします。デフォルトは2です。 |
| `````prefix_length````` | 提案候補となるために一致する必要がある最小接頭辞文字数。デフォルトは1です。この数を増やすとスペルチェックのパフォーマンスが向上します。通常、誤字は用語の最初に発生しません。 |
| `````min_word_length````` | サジェストテキスト用語が含まれるために必要な最小長さ。デフォルトは`````4`````です。 |
| `````shard_size````` | 各個別シャードから取得される最大提案数を設定します。リデュースフェーズでは、`````size`````オプションに基づいて上位Nの提案のみが返されます。デフォルトは`````size`````オプションです。これを`````size`````よりも高い値に設定すると、パフォーマンスのコストでスペル修正のためのより正確な文書頻度を取得できます。用語がシャード間で分割されるため、スペル修正のシャードレベルの文書頻度は正確でない場合があります。これを増やすと、これらの文書頻度がより正確になります。 |
| `````max_inspections````` | シャードレベルでより多くの候補スペル修正を検査するために`````shard_size`````と掛け算するために使用される係数。パフォーマンスのコストで精度を向上させることができます。デフォルトは5です。 |
| `````min_doc_freq````` | 提案が出現する文書の最小しきい値。この値は絶対数または文書数の相対的な割合として指定できます。これにより、高頻度の用語のみを提案することで品質が向上します。デフォルトは0fで、無効になっています。1より大きい値が指定された場合、数は小数であってはなりません。シャードレベルの文書頻度がこのオプションに使用されます。 |
| `````max_term_freq````` | 提案テキストトークンが含まれるために存在できる文書の最大しきい値。相対的な割合の数(例:0.4)または文書頻度を表す絶対数であることができます。1より大きい値が指定された場合、小数は指定できません。デフォルトは0.01fです。これは、通常正しく綴られている高頻度の用語をスペルチェックから除外するために使用できます。これにより、スペルチェックのパフォーマンスも向上します。シャードレベルの文書頻度がこのオプションに使用されます。 |
| `````string_distance````` | 提案された用語がどれだけ類似しているかを比較するために使用する文字列距離の実装。指定できる5つの可能な値:
- `````internal`````: デフォルトはdamerau\_levenshteinに基づいていますが、インデックス内の用語の文字列距離を比較するために最適化されています。
- `````damerau_levenshtein`````: Damerau-Levenshteinアルゴリズムに基づく文字列距離アルゴリズム。
- `````levenshtein`````: Levenshtein編集距離アルゴリズムに基づく文字列距離アルゴリズム。
- `````jaro_winkler`````: Jaro-Winklerアルゴリズムに基づく文字列距離アルゴリズム。
- `````ngram`````: 文字n-グラムに基づく文字列距離アルゴリズム。
## Phrase Suggester
`````term`````サジェスターは、特定の文字列距離内でトークンごとに単語の代替を取得するための非常に便利なAPIを提供します。このAPIは、ストリーム内の各トークンに個別にアクセスできるようにし、サジェスト選択はAPI消費者に委ねられます。しかし、しばしば事前に選択された提案が必要であり、エンドユーザーに提示されます。`````phrase`````サジェスターは、`````term`````サジェスターの上に追加のロジックを追加し、`````ngram-language`````モデルに基づいて重み付けされた個々のトークンの代わりに、全体の修正されたフレーズを選択します。実際には、このサジェスターは共起と頻度に基づいてどのトークンを選択するかについてより良い決定を下すことができます。
#### API Example
一般的に、`````phrase`````サジェスターは機能するために特別なマッピングが必要です。このページの`````phrase`````サジェスターの例では、機能するために次のマッピングが必要です。`````reverse`````アナライザーは、最後の例でのみ使用されます。
#### Python
``````python
resp = client.indices.create(
index="test",
settings={
"index": {
"number_of_shards": 1,
"analysis": {
"analyzer": {
"trigram": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"shingle"
]
},
"reverse": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"reverse"
]
}
},
"filter": {
"shingle": {
"type": "shingle",
"min_shingle_size": 2,
"max_shingle_size": 3
}
}
}
}
},
mappings={
"properties": {
"title": {
"type": "text",
"fields": {
"trigram": {
"type": "text",
"analyzer": "trigram"
},
"reverse": {
"type": "text",
"analyzer": "reverse"
}
}
}
}
},
)
print(resp)
resp1 = client.index(
index="test",
refresh=True,
document={
"title": "noble warriors"
},
)
print(resp1)
resp2 = client.index(
index="test",
refresh=True,
document={
"title": "nobel prize"
},
)
print(resp2)
`
Ruby
response = client.indices.create(
index: 'test',
body: {
settings: {
index: {
number_of_shards: 1,
analysis: {
analyzer: {
trigram: {
type: 'custom',
tokenizer: 'standard',
filter: [
'lowercase',
'shingle'
]
},
reverse: {
type: 'custom',
tokenizer: 'standard',
filter: [
'lowercase',
'reverse'
]
}
},
filter: {
shingle: {
type: 'shingle',
min_shingle_size: 2,
max_shingle_size: 3
}
}
}
}
},
mappings: {
properties: {
title: {
type: 'text',
fields: {
trigram: {
type: 'text',
analyzer: 'trigram'
},
reverse: {
type: 'text',
analyzer: 'reverse'
}
}
}
}
}
}
)
puts response
response = client.index(
index: 'test',
refresh: true,
body: {
title: 'noble warriors'
}
)
puts response
response = client.index(
index: 'test',
refresh: true,
body: {
title: 'nobel prize'
}
)
puts response
Js
const response = await client.indices.create({
index: "test",
settings: {
index: {
number_of_shards: 1,
analysis: {
analyzer: {
trigram: {
type: "custom",
tokenizer: "standard",
filter: ["lowercase", "shingle"],
},
reverse: {
type: "custom",
tokenizer: "standard",
filter: ["lowercase", "reverse"],
},
},
filter: {
shingle: {
type: "shingle",
min_shingle_size: 2,
max_shingle_size: 3,
},
},
},
},
},
mappings: {
properties: {
title: {
type: "text",
fields: {
trigram: {
type: "text",
analyzer: "trigram",
},
reverse: {
type: "text",
analyzer: "reverse",
},
},
},
},
},
});
console.log(response);
const response1 = await client.index({
index: "test",
refresh: "true",
document: {
title: "noble warriors",
},
});
console.log(response1);
const response2 = await client.index({
index: "test",
refresh: "true",
document: {
title: "nobel prize",
},
});
console.log(response2);
Console
PUT test
{
"settings": {
"index": {
"number_of_shards": 1,
"analysis": {
"analyzer": {
"trigram": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase","shingle"]
},
"reverse": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase","reverse"]
}
},
"filter": {
"shingle": {
"type": "shingle",
"min_shingle_size": 2,
"max_shingle_size": 3
}
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"trigram": {
"type": "text",
"analyzer": "trigram"
},
"reverse": {
"type": "text",
"analyzer": "reverse"
}
}
}
}
}
}
POST test/_doc?refresh=true
{"title": "noble warriors"}
POST test/_doc?refresh=true
{"title": "nobel prize"}
アナライザーとマッピングが設定されると、phrase
サジェスターをterm
サジェスターを使用するのと同じ場所で使用できます。
Python
resp = client.search(
index="test",
suggest={
"text": "noble prize",
"simple_phrase": {
"phrase": {
"field": "title.trigram",
"size": 1,
"gram_size": 3,
"direct_generator": [
{
"field": "title.trigram",
"suggest_mode": "always"
}
],
"highlight": {
"pre_tag": "<em>",
"post_tag": "</em>"
}
}
}
},
)
print(resp)
Js
const response = await client.search({
index: "test",
suggest: {
text: "noble prize",
simple_phrase: {
phrase: {
field: "title.trigram",
size: 1,
gram_size: 3,
direct_generator: [
{
field: "title.trigram",
suggest_mode: "always",
},
],
highlight: {
pre_tag: "<em>",
post_tag: "</em>",
},
},
},
},
});
console.log(response);
Console
POST test/_search
{
"suggest": {
"text": "noble prize",
"simple_phrase": {
"phrase": {
"field": "title.trigram",
"size": 1,
"gram_size": 3,
"direct_generator": [ {
"field": "title.trigram",
"suggest_mode": "always"
} ],
"highlight": {
"pre_tag": "<em>",
"post_tag": "</em>"
}
}
}
}
}
レスポンスには、最も可能性の高いスペル修正によってスコア付けされた提案が含まれています。この場合、期待される修正「ノーベル賞」を受け取りました。
Console-Result
{
"_shards": ...
"hits": ...
"timed_out": false,
"took": 3,
"suggest": {
"simple_phrase" : [
{
"text" : "noble prize",
"offset" : 0,
"length" : 11,
"options" : [ {
"text" : "nobel prize",
"highlighted": "<em>nobel</em> prize",
"score" : 0.48614594
}]
}
]
}
}
Basic Phrase suggest API parameters
field |
言語モデルのn-グラムルックアップに使用されるフィールドの名前。サジェスターはこのフィールドを使用して修正をスコアリングする統計を取得します。このフィールドは必須です。 |
gram_size |
field のn-グラム(シングル)サイズの最大値を設定します。フィールドにn-グラム(シングル)が含まれていない場合、これは省略するか1 に設定する必要があります。Elasticsearchは、指定されたfield に基づいてグラムサイズを検出しようとします。フィールドがshingle フィルターを使用している場合、gram_size は明示的に設定されていない場合、max_shingle_size に設定されます。 |
real_word_error_likelihood |
用語が辞書に存在していても誤って綴られる可能性。デフォルトは0.95 で、実際の単語の5%が誤って綴られています。 |
confidence |
信頼レベルは、他のサジェスト候補のしきい値として使用される入力フレーズスコアに適用される係数を定義します。しきい値よりもスコアが高い候補のみが結果に含まれます。たとえば、1.0 の信頼レベルは、入力フレーズよりもスコアが高い提案のみを返します。0.0 に設定すると、上位Nの候補が返されます。デフォルトは1.0 です。 |
max_errors |
修正を形成するために誤って綴られていると見なされる用語の最大割合。このメソッドは、実際のクエリ用語の割合として[0..1) の範囲内の浮動小数点値を受け入れるか、クエリ用語の絶対数として>=1 の数値を受け入れます。デフォルトは1.0 に設定されており、誤って綴られた用語が1つだけの修正が返されます。これを高く設定しすぎると、パフォーマンスに悪影響を与える可能性があります。1 や2 のような低い値が推奨されます。そうでなければ、サジェスト呼び出しにかかる時間がクエリ実行にかかる時間を超える可能性があります。 |
separator |
ビグラムフィールド内の用語を区切るために使用されるセパレーター。設定されていない場合、ホワイトスペース文字がセパレーターとして使用されます。 |
size |
各個別のクエリ用語に対して生成される候補の数。3 や5 のような低い数は通常良好な結果を生み出します。これを上げると、より高い編集距離の用語が出てくる可能性があります。デフォルトは5 です。 |
analyzer |
サジェストテキストを分析するためのアナライザーを設定します。デフォルトはfield を介して渡されたサジェストフィールドの検索アナライザーです。 |
shard_size |
各個別シャードから取得される提案された用語の最大数を設定します。リデュースフェーズでは、size オプションに基づいて上位Nの提案のみが返されます。デフォルトは5 です。 |
text |
提案を提供するためのテキスト/クエリを設定します。 |
highlight |
サジェストハイライトを設定します。提供されていない場合、highlighted フィールドは返されません。提供されている場合、pre_tag とpost_tag を正確に含む必要があり、変更されたトークンの周りにラップされます。複数のトークンが連続して変更された場合、変更されたトークンのフレーズ全体がラップされ、各トークンではなくなります。 |
| collate
| 指定されたquery
に対して各提案をチェックし、インデックスに一致する文書が存在しない提案をプルーニングします。提案のコレートクエリは、提案が生成されたローカルシャードでのみ実行されます。query
は指定する必要があり、テンプレート化できます。
検索テンプレートを参照してください。現在の提案は自動的に{{suggestion}}
変数として利用可能になり、クエリで使用する必要があります。独自のテンプレートparams
を指定することもできます。suggestion
値は、指定した変数に追加されます。さらに、prune
を指定して、すべてのフレーズ提案が返されるかどうかを制御できます。true
に設定すると、提案には追加のオプションcollate_match
があり、フレーズに一致する文書が見つかった場合はtrue
、そうでない場合はfalse
になります。
#### Python
``````python
resp = client.search(
index="test",
suggest={
"text": "noble prize",
"simple_phrase": {
"phrase": {
"field": "title.trigram",
"size": 1,
"direct_generator": [
{
"field": "title.trigram",
"suggest_mode": "always",
"min_word_length": 1
}
],
"collate": {
"query": {
"source": {
"match": {
"{{field_name}}": "{{suggestion}}"
}
}
},
"params": {
"field_name": "title"
},
"prune": True
}
}
}
},
)
print(resp)
`
Js
const response = await client.search({
index: "test",
suggest: {
text: "noble prize",
simple_phrase: {
phrase: {
field: "title.trigram",
size: 1,
direct_generator: [
{
field: "title.trigram",
suggest_mode: "always",
min_word_length: 1,
},
],
collate: {
query: {
source: {
match: {
"{{field_name}}": "{{suggestion}}",
},
},
},
params: {
field_name: "title",
},
prune: true,
},
},
},
},
});
console.log(response);
Console
POST test/_search
{
"suggest": {
"text" : "noble prize",
"simple_phrase" : {
"phrase" : {
"field" : "title.trigram",
"size" : 1,
"direct_generator" : [ {
"field" : "title.trigram",
"suggest_mode" : "always",
"min_word_length" : 1
} ],
"collate": {
"query": {
"source" : {
"match": {
"{{field_name}}" : "{{suggestion}}"
}
}
},
"params": {"field_name" : "title"},
"prune": true
}
}
}
}
}
このクエリは、各提案ごとに1回実行されます。 | |
{{suggestion}} 変数は、各提案のテキストに置き換えられます。 |
|
追加のfield_name 変数がparams で指定され、match クエリで使用されます。 |
|
すべての提案は、生成されたフレーズが文書に一致したかどうかを示す追加のcollate_match オプションと共に返されます。 |
Smoothing Models
| | |
| --- | --- |
| `````stupid_backoff````` | 高次のカウントが`````0`````の場合、低次のn-グラムモデルにバックオフし、低次のn-グラムモデルを定数因子で割引く単純なバックオフモデル。デフォルトの`````discount`````は`````0.4`````です。Stupid Backoffがデフォルトモデルです。 |
| `````laplace````` | すべてのカウントに定数(通常は`````1.0`````またはそれ以下)を追加して重みをバランスさせる加法スムージングモデル。デフォルトの`````alpha`````は`````0.5`````です。 |
| `````linear_interpolation````` | ユーザーが提供した重み(ラムダ)に基づいて、ユニグラム、バイグラム、トライグラムの加重平均を取るスムージングモデル。線形補間にはデフォルト値はありません。すべてのパラメータ(`````trigram_lambda`````、`````bigram_lambda`````、`````unigram_lambda`````)を提供する必要があります。
#### Python
``````python
resp = client.search(
index="test",
suggest={
"text": "obel prize",
"simple_phrase": {
"phrase": {
"field": "title.trigram",
"size": 1,
"smoothing": {
"laplace": {
"alpha": 0.7
}
}
}
}
},
)
print(resp)
`
Js
const response = await client.search({
index: "test",
suggest: {
text: "obel prize",
simple_phrase: {
phrase: {
field: "title.trigram",
size: 1,
smoothing: {
laplace: {
alpha: 0.7,
},
},
},
},
},
});
console.log(response);
Console
POST test/_search
{
"suggest": {
"text" : "obel prize",
"simple_phrase" : {
"phrase" : {
"field" : "title.trigram",
"size" : 1,
"smoothing" : {
"laplace" : {
"alpha" : 0.7
}
}
}
}
}
}
Candidate Generators
現在、`````direct_generator`````のみがサポートされている候補生成器のタイプです。フレーズサジェストAPIは、`````direct_generator`````キーの下に生成器のリストを受け入れます。リスト内の各生成器は、元のテキスト内の用語ごとに呼び出されます。
#### Direct Generators
直接生成器は、次のパラメータをサポートします:
| | |
| --- | --- |
| `````field````` | 候補提案を取得するフィールド。これはグローバルまたは提案ごとに設定する必要がある必須オプションです。 |
| `````size````` | サジェストテキストトークンごとに返される最大修正数。 |
| `````suggest_mode````` | サジェストモードは、各シャードで生成された提案に含まれる提案を制御します。`````always`````以外のすべての値は、各シャードでテストするために少ない提案を生成するための最適化と見なすことができ、各シャードで生成された提案を組み合わせるときに再チェックされません。したがって、`````missing`````は、他のシャードがそれらを含んでいても、シャードに存在しない用語の提案を生成します。これらは`````confidence`````を使用してフィルタリングする必要があります。指定できる3つの可能な値:<br>- `````missing`````: シャードに存在しない用語の提案のみを生成します。これがデフォルトです。<br>- `````popular`````: 元の用語よりも多くの文書に出現する用語のみを提案します。<br>- `````always`````: サジェストテキスト内の用語に基づいて一致する提案を提案します。 |
| `````max_edits````` | 提案として考慮されるために候補提案が持つことができる最大編集距離。1と2の間の値のみです。他の値は不正なリクエストエラーを引き起こします。デフォルトは2です。 |
| `````prefix_length````` | 提案候補となるために一致する必要がある最小接頭辞文字数。デフォルトは1です。この数を増やすとスペルチェックのパフォーマンスが向上します。通常、誤字は用語の最初に発生しません。 |
| `````min_word_length````` | サジェストテキスト用語が含まれるために必要な最小長さ。デフォルトは4です。 |
| `````max_inspections````` | シャードレベルでより多くの候補スペル修正を検査するために`````shard_size`````と掛け算するために使用される係数。パフォーマンスのコストで精度を向上させることができます。デフォルトは5です。 |
| `````min_doc_freq````` | 提案が出現する文書の最小しきい値。この値は絶対数または文書数の相対的な割合として指定できます。これにより、高頻度の用語のみを提案することで品質が向上します。デフォルトは0fで、無効になっています。1より大きい値が指定された場合、数は小数であってはなりません。シャードレベルの文書頻度がこのオプションに使用されます。 |
| `````max_term_freq````` | 提案テキストトークンが含まれるために存在できる文書の最大しきい値。相対的な割合の数(例:0.4)または文書頻度を表す絶対数であることができます。1より大きい値が指定された場合、小数は指定できません。デフォルトは0.01fです。これは、通常正しく綴られている高頻度の用語をスペルチェックから除外するために使用できます。これにより、スペルチェックのパフォーマンスも向上します。シャードレベルの文書頻度がこのオプションに使用されます。 |
| `````pre_filter````` | この候補生成器に渡される各トークンに適用されるフィルター(アナライザー)。このフィルターは、候補が生成される前に元のトークンに適用されます。 |
| `````post_filter````` | 実際のフレーズスコアラーに渡される前に生成されたトークンに適用されるフィルター(アナライザー)。
以下の例は、2つの生成器を持つ`````phrase`````サジェスト呼び出しを示しています。最初のものは、通常のインデックス用語を含むフィールドを使用し、2番目のものは`````reverse`````フィルターを使用してインデックスされた用語を使用します(トークンは逆順にインデックスされます)。これは、直接生成器の制限を克服するために使用され、高性能の提案を提供するために定数接頭辞を必要とします。`````pre_filter`````と`````post_filter`````オプションは、通常のアナライザー名を受け入れます。
#### Python
``````python
resp = client.search(
index="test",
suggest={
"text": "obel prize",
"simple_phrase": {
"phrase": {
"field": "title.trigram",
"size": 1,
"direct_generator": [
{
"field": "title.trigram",
"suggest_mode": "always"
},
{
"field": "title.reverse",
"suggest_mode": "always",
"pre_filter": "reverse",
"post_filter": "reverse"
}
]
}
}
},
)
print(resp)
`
Js
const response = await client.search({
index: "test",
suggest: {
text: "obel prize",
simple_phrase: {
phrase: {
field: "title.trigram",
size: 1,
direct_generator: [
{
field: "title.trigram",
suggest_mode: "always",
},
{
field: "title.reverse",
suggest_mode: "always",
pre_filter: "reverse",
post_filter: "reverse",
},
],
},
},
},
});
console.log(response);
Console
POST test/_search
{
"suggest": {
"text" : "obel prize",
"simple_phrase" : {
"phrase" : {
"field" : "title.trigram",
"size" : 1,
"direct_generator" : [ {
"field" : "title.trigram",
"suggest_mode" : "always"
}, {
"field" : "title.reverse",
"suggest_mode" : "always",
"pre_filter" : "reverse",
"post_filter" : "reverse"
} ]
}
}
}
}
pre_filter
とpost_filter
は、候補が生成された後に同義語を注入するためにも使用できます。たとえば、クエリcaptain usq
に対して、用語usq
の候補usa
を生成することができ、これはamerica
の同義語です。これにより、このフレーズが十分に高いスコアを持っている場合、captain america
をユーザーに提示できます。
Completion Suggester
理想的には、自動補完機能は、ユーザーがすでに入力した内容に関連する即時フィードバックを提供するために、ユーザーが入力する速度と同じくらい速くあるべきです。したがって、`````completion`````サジェスターは速度の最適化が行われています。サジェスターは、高速なルックアップを可能にするデータ構造を使用しますが、構築にはコストがかかり、メモリに保存されます。
#### Mapping
[`````completion`````サジェスター](39d4e7248968ca4f.md#completion-suggester)を使用するには、提案を生成したいフィールドを`````completion`````タイプとしてマッピングします。これにより、フィールド値が高速補完のためにインデックスされます。
#### Python
``````python
resp = client.indices.create(
index="music",
mappings={
"properties": {
"suggest": {
"type": "completion"
}
}
},
)
print(resp)
`
Ruby
response = client.indices.create(
index: 'music',
body: {
mappings: {
properties: {
suggest: {
type: 'completion'
}
}
}
}
)
puts response
Js
const response = await client.indices.create({
index: "music",
mappings: {
properties: {
suggest: {
type: "completion",
},
},
},
});
console.log(response);
Console
PUT music
{
"mappings": {
"properties": {
"suggest": {
"type": "completion"
}
}
}
}
Parameters for completion fields
| | |
| --- | --- |
| [`````analyzer`````](/read/elasticsearch-8-15/df0c1a6ddee71929.md "analyzer") | 使用するインデックスアナライザー。デフォルトは`````simple`````です。 |
| [`````search_analyzer`````](/read/elasticsearch-8-15/b0cfe1799c03b42e.md "search_analyzer") | 使用する検索アナライザー。デフォルトは`````analyzer`````の値です。 |
| `````preserve_separators````` | セパレーターを保持します。デフォルトは`````true`````です。無効にすると、`````foof`````の提案を行う場合、`````Foo Fighters`````で始まるフィールドを見つけることができます。 |
| `````preserve_position_increments````` | 位置のインクリメントを有効にします。デフォルトは`````true`````です。無効にすると、ストップワードアナライザーを使用している場合、`````The Beatles`````の提案を行う場合、`````b`````で始まるフィールドを取得することができます。**注意**:データを豊かにすることができる場合、`````Beatles`````と`````The Beatles`````の2つの入力をインデックスすることで、単純なアナライザーを変更する必要はありません。 |
| `````max_input_length````` | 単一の入力の長さを制限します。デフォルトは`````50````` UTF-16コードポイントです。この制限は、基礎となるデータ構造が膨張するのを防ぐために、インデックス時にのみ使用されます。ほとんどのユースケースは、デフォルト値によって影響を受けません。接頭辞補完は、通常、数文字以上の接頭辞に成長することはほとんどありません。
#### Indexing
提案は他のフィールドと同様にインデックスします。提案は、`````input`````とオプションの`````weight`````属性で構成されます。`````input`````は、提案クエリによって一致することが期待されるテキストであり、`````weight`````は提案がどのようにスコアリングされるかを決定します。提案をインデックスする方法は次のとおりです:
#### Python
``````python
resp = client.index(
index="music",
id="1",
refresh=True,
document={
"suggest": {
"input": [
"Nevermind",
"Nirvana"
],
"weight": 34
}
},
)
print(resp)
`
Ruby
response = client.index(
index: 'music',
id: 1,
refresh: true,
body: {
suggest: {
input: [
'Nevermind',
'Nirvana'
],
weight: 34
}
}
)
puts response
Js
const response = await client.index({
index: "music",
id: 1,
refresh: "true",
document: {
suggest: {
input: ["Nevermind", "Nirvana"],
weight: 34,
},
},
});
console.log(response);
Console
PUT music/_doc/1?refresh
{
"suggest" : {
"input": [ "Nevermind", "Nirvana" ],
"weight" : 34
}
}
サポートされている次のパラメータ:
input |
保存する入力。これは文字列の配列または単一の文字列である可能性があります。このフィールドは必須です。この値には、次のUTF-16制御文字を含めることはできません: - \u0000 (null)- \u001f (情報区切り子1)- \u001e (情報区切り子2) |
| weight
| 正の整数または正の整数を含む文字列で、重みを定義し、提案をランク付けすることができます。このフィールドはオプションです。
ドキュメントに対して複数の提案を次のようにインデックスできます:
Python
resp = client.index(
index="music",
id="1",
refresh=True,
document={
"suggest": [
{
"input": "Nevermind",
"weight": 10
},
{
"input": "Nirvana",
"weight": 3
}
]
},
)
print(resp)
Ruby
response = client.index(
index: 'music',
id: 1,
refresh: true,
body: {
suggest: [
{
input: 'Nevermind',
weight: 10
},
{
input: 'Nirvana',
weight: 3
}
]
}
)
puts response
Js
const response = await client.index({
index: "music",
id: 1,
refresh: "true",
document: {
suggest: [
{
input: "Nevermind",
weight: 10,
},
{
input: "Nirvana",
weight: 3,
},
],
},
});
console.log(response);
Console
PUT music/_doc/1?refresh
{
"suggest": [
{
"input": "Nevermind",
"weight": 10
},
{
"input": "Nirvana",
"weight": 3
}
]
}
次の省略形を使用できます。提案に重みを指定することはできません。
Python
resp = client.index(
index="music",
id="1",
refresh=True,
document={
"suggest": [
"Nevermind",
"Nirvana"
]
},
)
print(resp)
Ruby
response = client.index(
index: 'music',
id: 1,
refresh: true,
body: {
suggest: [
'Nevermind',
'Nirvana'
]
}
)
puts response
Js
const response = await client.index({
index: "music",
id: 1,
refresh: "true",
document: {
suggest: ["Nevermind", "Nirvana"],
},
});
console.log(response);
Console
PUT music/_doc/1?refresh
{
"suggest" : [ "Nevermind", "Nirvana" ]
}
Querying
提案は通常通り機能しますが、サジェストタイプをcompletion
として指定する必要があります。提案はほぼリアルタイムであり、新しい提案はリフレッシュによって表示される可能性があり、一度削除された文書は決して表示されません。このリクエスト:
Python
resp = client.search(
index="music",
pretty=True,
suggest={
"song-suggest": {
"prefix": "nir",
"completion": {
"field": "suggest"
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'music',
pretty: true,
body: {
suggest: {
"song-suggest": {
prefix: 'nir',
completion: {
field: 'suggest'
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "music",
pretty: "true",
suggest: {
"song-suggest": {
prefix: "nir",
completion: {
field: "suggest",
},
},
},
});
console.log(response);
Console
POST music/_search?pretty
{
"suggest": {
"song-suggest": {
"prefix": "nir",
"completion": {
"field": "suggest"
}
}
}
}
提案を検索するために使用される接頭辞 | |
提案の種類 | |
提案を検索するフィールドの名前 |
Console-Result
{
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits": ...
"took": 2,
"timed_out": false,
"suggest": {
"song-suggest" : [ {
"text" : "nir",
"offset" : 0,
"length" : 3,
"options" : [ {
"text" : "Nirvana",
"_index": "music",
"_id": "1",
"_score": 1.0,
"_source": {
"suggest": ["Nevermind", "Nirvana"]
}
} ]
} ]
}
}
_source
メタデータフィールドは有効にする必要があります。これはデフォルトの動作であり、_source
を提案と共に返すことを可能にします。
提案のために設定された重みは _score
として返されます。text
フィールドは、インデックスされた提案の input
を使用します。提案はデフォルトで完全なドキュメント _source
を返します。_source
のサイズは、ディスクフェッチとネットワーク転送のオーバーヘッドのためにパフォーマンスに影響を与える可能性があります。ネットワークのオーバーヘッドを削減するために、ソースフィルタリングを使用して _source
から不要なフィールドをフィルタリングし、_source
のサイズを最小限に抑えてください。_suggest エンドポイントはソースフィルタリングをサポートしていませんが、_search
エンドポイントで suggest を使用することは可能です:
Python
resp = client.search(
index="music",
source="suggest",
suggest={
"song-suggest": {
"prefix": "nir",
"completion": {
"field": "suggest",
"size": 5
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'music',
body: {
_source: 'suggest',
suggest: {
"song-suggest": {
prefix: 'nir',
completion: {
field: 'suggest',
size: 5
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "music",
_source: "suggest",
suggest: {
"song-suggest": {
prefix: "nir",
completion: {
field: "suggest",
size: 5,
},
},
},
});
console.log(response);
Console
POST music/_search
{
"_source": "suggest",
"suggest": {
"song-suggest": {
"prefix": "nir",
"completion": {
"field": "suggest",
"size": 5
}
}
}
}
ソースをフィルタリングして suggest フィールドのみを返す |
|
提案を検索するフィールドの名前 | |
返す提案の数 |
Console-Result
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"suggest": {
"song-suggest": [ {
"text": "nir",
"offset": 0,
"length": 3,
"options": [ {
"text": "Nirvana",
"_index": "music",
"_id": "1",
"_score": 1.0,
"_source": {
"suggest": [ "Nevermind", "Nirvana" ]
}
} ]
} ]
}
}
基本的な補完サジェスタークエリは、以下のパラメータをサポートしています:
field |
クエリを実行するフィールドの名前(必須)。 |
size |
返す提案の数(デフォルトは 5 )。 |
skip_duplicates |
重複提案をフィルタリングするかどうか(デフォルトは false )。 |
補完サジェスターはインデックス内のすべてのドキュメントを考慮します。特定のドキュメントのサブセットをクエリする方法については、コンテキストサジェスターを参照してください。
複数のシャードにまたがる補完クエリの場合、サジェストは2つのフェーズで実行され、最後のフェーズでシャードから関連するドキュメントを取得します。これは、サジェストが複数のシャードにまたがる場合、ドキュメントフェッチのオーバーヘッドのために単一のシャードに対して補完リクエストを実行する方がパフォーマンスが良いことを意味します。補完のパフォーマンスを最適化するためには、補完を単一のシャードインデックスにインデックスすることをお勧めします。シャードサイズによるヒープ使用量が高い場合でも、補完パフォーマンスを最適化するのではなく、インデックスを複数のシャードに分割することをお勧めします。
Skip duplicate suggestions
クエリは異なるドキュメントからの重複提案を返すことがあります。この動作を変更するには、skip_duplicates
を true に設定することが可能です。設定すると、このオプションは結果から重複提案を持つドキュメントをフィルタリングします。
Python
resp = client.search(
index="music",
pretty=True,
suggest={
"song-suggest": {
"prefix": "nor",
"completion": {
"field": "suggest",
"skip_duplicates": True
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'music',
pretty: true,
body: {
suggest: {
"song-suggest": {
prefix: 'nor',
completion: {
field: 'suggest',
skip_duplicates: true
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "music",
pretty: "true",
suggest: {
"song-suggest": {
prefix: "nor",
completion: {
field: "suggest",
skip_duplicates: true,
},
},
},
});
console.log(response);
Console
POST music/_search?pretty
{
"suggest": {
"song-suggest": {
"prefix": "nor",
"completion": {
"field": "suggest",
"skip_duplicates": true
}
}
}
}
true に設定すると、このオプションは検索を遅くする可能性があります。なぜなら、トップ N を見つけるために訪問する必要がある提案が増えるからです。
Fuzzy queries
補完サジェスターはファジークエリもサポートしています。これは、検索にタイプミスがあっても結果を得ることができることを意味します。
Python
resp = client.search(
index="music",
pretty=True,
suggest={
"song-suggest": {
"prefix": "nor",
"completion": {
"field": "suggest",
"fuzzy": {
"fuzziness": 2
}
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'music',
pretty: true,
body: {
suggest: {
"song-suggest": {
prefix: 'nor',
completion: {
field: 'suggest',
fuzzy: {
fuzziness: 2
}
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "music",
pretty: "true",
suggest: {
"song-suggest": {
prefix: "nor",
completion: {
field: "suggest",
fuzzy: {
fuzziness: 2,
},
},
},
},
});
console.log(response);
Console
POST music/_search?pretty
{
"suggest": {
"song-suggest": {
"prefix": "nor",
"completion": {
"field": "suggest",
"fuzzy": {
"fuzziness": 2
}
}
}
}
}
クエリ prefix
に最も長い接頭辞を共有する提案は、より高いスコアが付けられます。
ファジークエリは特定のファジーパラメータを取ることができます。以下のパラメータがサポートされています:
fuzziness |
ファジネスファクター、デフォルトは AUTO 。許可されている設定については Fuzziness を参照してください。 |
transpositions |
true に設定されている場合、転置は2つの変更の代わりに1つの変更としてカウントされ、デフォルトは true |
min_length |
ファジー提案が返される前の入力の最小長さ、デフォルトは 3 |
prefix_length |
ファジー代替案のチェックが行われない入力の最小長さ、デフォルトは 1 |
unicode_aware |
true の場合、すべての測定(ファジー編集距離、転置、長さなど)は、バイトではなく Unicode コードポイントで測定されます。これは生のバイトよりもわずかに遅く、デフォルトでは false に設定されています。 |
デフォルト値を維持したいが、ファジーを使用したい場合は、fuzzy: {}
または fuzzy: true
を使用できます。
Regex queries
補完サジェスターは正規表現クエリもサポートしており、接頭辞を正規表現として表現することができます。
Python
resp = client.search(
index="music",
pretty=True,
suggest={
"song-suggest": {
"regex": "n[ever|i]r",
"completion": {
"field": "suggest"
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'music',
pretty: true,
body: {
suggest: {
"song-suggest": {
regex: 'n[ever|i]r',
completion: {
field: 'suggest'
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "music",
pretty: "true",
suggest: {
"song-suggest": {
regex: "n[ever|i]r",
completion: {
field: "suggest",
},
},
},
});
console.log(response);
Console
POST music/_search?pretty
{
"suggest": {
"song-suggest": {
"regex": "n[ever|i]r",<br> "completion": {<br> "field": "suggest"<br> }<br> }<br> }<br>}<br>``````<br><br>正規表現クエリは特定の正規表現パラメータを取ることができます。以下のパラメータがサポートされています: <br><br>
| | |
| --- | --- |
| `````flags````` | 可能なフラグは `````ALL`````(デフォルト)、`````ANYSTRING`````、`````COMPLEMENT`````、<br><br>`````EMPTY`````、`````INTERSECTION`````、`````INTERVAL`````、または `````NONE````` です。意味については [regexp-syntax](/read/elasticsearch-8-15/18c0a8d633e2b8f9.md "Regexp query")<br><br>を参照してください。 |
| `````max_determinized_states````` | 正規表現は危険です。なぜなら、無害に見えるものを偶然に作成してしまうことが容易であり、それが Lucene の実行に必要な指数関数的な数の内部決定化オートマトン状態(および対応する RAM と CPU)を要求するからです。Lucene は `````max_determinized_states````` 設定(デフォルトは 10000)を使用してこれを防ぎます。この制限を引き上げることで、より複雑な正規表現を実行できるようになります。
## Context Suggester
補完サジェスターはインデックス内のすべてのドキュメントを考慮しますが、提案を特定の基準でフィルタリングおよび/またはブーストすることが望ましいことがよくあります。たとえば、特定のアーティストによってフィルタリングされた曲のタイトルを提案したり、ジャンルに基づいて曲のタイトルをブーストしたりすることができます。
提案のフィルタリングおよび/またはブーストを実現するには、補完フィールドを構成する際にコンテキストマッピングを追加できます。補完フィールドに対して複数のコンテキストマッピングを定義できます。各コンテキストマッピングには一意の名前とタイプがあります。2つのタイプがあります: `````category````` と `````geo`````。コンテキストマッピングはフィールドマッピングの `````contexts````` パラメータの下で構成されます。
コンテキストを提供することは、コンテキストが有効な補完フィールドをインデックスおよびクエリする際に必須です。
補完フィールドのコンテキストマッピングの最大許可数は 10 です。
以下は、各補完フィールドのための2つのコンテキストマッピングを持つタイプを定義します:
#### Python
``````python
resp = client.indices.create(
index="place",
mappings={
"properties": {
"suggest": {
"type": "completion",
"contexts": [
{
"name": "place_type",
"type": "category"
},
{
"name": "location",
"type": "geo",
"precision": 4
}
]
}
}
},
)
print(resp)
resp1 = client.indices.create(
index="place_path_category",
mappings={
"properties": {
"suggest": {
"type": "completion",
"contexts": [
{
"name": "place_type",
"type": "category",
"path": "cat"
},
{
"name": "location",
"type": "geo",
"precision": 4,
"path": "loc"
}
]
},
"loc": {
"type": "geo_point"
}
}
},
)
print(resp1)
Ruby
response = client.indices.create(
index: 'place',
body: {
mappings: {
properties: {
suggest: {
type: 'completion',
contexts: [
{
name: 'place_type',
type: 'category'
},
{
name: 'location',
type: 'geo',
precision: 4
}
]
}
}
}
}
)
puts response
response = client.indices.create(
index: 'place_path_category',
body: {
mappings: {
properties: {
suggest: {
type: 'completion',
contexts: [
{
name: 'place_type',
type: 'category',
path: 'cat'
},
{
name: 'location',
type: 'geo',
precision: 4,
path: 'loc'
}
]
},
loc: {
type: 'geo_point'
}
}
}
}
)
puts response
Js
const response = await client.indices.create({
index: "place",
mappings: {
properties: {
suggest: {
type: "completion",
contexts: [
{
name: "place_type",
type: "category",
},
{
name: "location",
type: "geo",
precision: 4,
},
],
},
},
},
});
console.log(response);
const response1 = await client.indices.create({
index: "place_path_category",
mappings: {
properties: {
suggest: {
type: "completion",
contexts: [
{
name: "place_type",
type: "category",
path: "cat",
},
{
name: "location",
type: "geo",
precision: 4,
path: "loc",
},
],
},
loc: {
type: "geo_point",
},
},
},
});
console.log(response1);
Console
PUT place
{
"mappings": {
"properties": {
"suggest": {
"type": "completion",
"contexts": [
{
"name": "place_type",
"type": "category"
},
{
"name": "location",
"type": "geo",
"precision": 4
}
]
}
}
}
}
PUT place_path_category
{
"mappings": {
"properties": {
"suggest": {
"type": "completion",
"contexts": [
{
"name": "place_type",
"type": "category",
"path": "cat"
},
{
"name": "location",
"type": "geo",
"precision": 4,
"path": "loc"
}
]
},
"loc": {
"type": "geo_point"
}
}
}
}
place_type という名前の category コンテキストを定義し、カテゴリは提案と共に送信される必要があります。 |
|
location という名前の geo コンテキストを定義し、カテゴリは提案と共に送信される必要があります。 |
|
category という名前の place_type コンテキストを定義し、カテゴリは cat フィールドから読み取られます。 |
|
geo という名前の location コンテキストを定義し、カテゴリは loc フィールドから読み取られます。 |
コンテキストマッピングを追加すると、補完フィールドのインデックスサイズが増加します。補完インデックスは完全にヒープに常駐しており、インデックス統計を使用して補完フィールドインデックスサイズを監視できます。
Category Context
category
コンテキストは、インデックス時に提案に1つ以上のカテゴリを関連付けることを可能にします。クエリ時には、提案は関連付けられたカテゴリによってフィルタリングおよびブーストされることができます。
マッピングは、上記の place_type
フィールドのように設定されます。path
が定義されている場合、カテゴリはドキュメント内のそのパスから読み取られます。そうでない場合、提案フィールドに次のように送信する必要があります:
Python
resp = client.index(
index="place",
id="1",
document={
"suggest": {
"input": [
"timmy's",
"starbucks",
"dunkin donuts"
],
"contexts": {
"place_type": [
"cafe",
"food"
]
}
}
},
)
print(resp)
Ruby
response = client.index(
index: 'place',
id: 1,
body: {
suggest: {
input: [
"timmy's",
'starbucks',
'dunkin donuts'
],
contexts: {
place_type: [
'cafe',
'food'
]
}
}
}
)
puts response
Js
const response = await client.index({
index: "place",
id: 1,
document: {
suggest: {
input: ["timmy's", "starbucks", "dunkin donuts"],
contexts: {
place_type: ["cafe", "food"],
},
},
},
});
console.log(response);
Console
PUT place/_doc/1
{
"suggest": {
"input": [ "timmy's", "starbucks", "dunkin donuts" ],
"contexts": {
"place_type": [ "cafe", "food" ]
}
}
}
これらの提案は cafe と food カテゴリに関連付けられます。 |
マッピングに path
があった場合、次のインデックスリクエストでカテゴリを追加するのに十分です:
Python
resp = client.index(
index="place_path_category",
id="1",
document={
"suggest": [
"timmy's",
"starbucks",
"dunkin donuts"
],
"cat": [
"cafe",
"food"
]
},
)
print(resp)
Ruby
response = client.index(
index: 'place_path_category',
id: 1,
body: {
suggest: [
"timmy's",
'starbucks',
'dunkin donuts'
],
cat: [
'cafe',
'food'
]
}
)
puts response
Js
const response = await client.index({
index: "place_path_category",
id: 1,
document: {
suggest: ["timmy's", "starbucks", "dunkin donuts"],
cat: ["cafe", "food"],
},
});
console.log(response);
Console
PUT place_path_category/_doc/1
{
"suggest": ["timmy's", "starbucks", "dunkin donuts"],
"cat": ["cafe", "food"]
}
これらの提案は cafe と food カテゴリに関連付けられます。 |
コンテキストマッピングが別のフィールドを参照し、カテゴリが明示的にインデックスされている場合、提案は両方のカテゴリセットでインデックスされます。
Category Query
提案は1つ以上のカテゴリによってフィルタリングできます。以下は、複数のカテゴリによって提案をフィルタリングします:
Python
resp = client.search(
index="place",
pretty=True,
suggest={
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"place_type": [
"cafe",
"restaurants"
]
}
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'place',
pretty: true,
body: {
suggest: {
place_suggestion: {
prefix: 'tim',
completion: {
field: 'suggest',
size: 10,
contexts: {
place_type: [
'cafe',
'restaurants'
]
}
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "place",
pretty: "true",
suggest: {
place_suggestion: {
prefix: "tim",
completion: {
field: "suggest",
size: 10,
contexts: {
place_type: ["cafe", "restaurants"],
},
},
},
},
});
console.log(response);
Console
POST place/_search?pretty
{
"suggest": {
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"place_type": [ "cafe", "restaurants" ]
}
}
}
}
}
クエリに複数のカテゴリまたはカテゴリコンテキストが設定されている場合、それらは論理和としてマージされます。これは、提案が提供されたコンテキスト値のいずれかを含む場合に一致することを意味します。
特定のカテゴリを持つ提案は、他の提案よりも高くブーストされることがあります。以下は、カテゴリによって提案をフィルタリングし、さらにいくつかのカテゴリに関連付けられた提案をブーストします:
Python
resp = client.search(
index="place",
pretty=True,
suggest={
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"place_type": [
{
"context": "cafe"
},
{
"context": "restaurants",
"boost": 2
}
]
}
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'place',
pretty: true,
body: {
suggest: {
place_suggestion: {
prefix: 'tim',
completion: {
field: 'suggest',
size: 10,
contexts: {
place_type: [
{
context: 'cafe'
},
{
context: 'restaurants',
boost: 2
}
]
}
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "place",
pretty: "true",
suggest: {
place_suggestion: {
prefix: "tim",
completion: {
field: "suggest",
size: 10,
contexts: {
place_type: [
{
context: "cafe",
},
{
context: "restaurants",
boost: 2,
},
],
},
},
},
},
});
console.log(response);
Console
POST place/_search?pretty
{
"suggest": {
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"place_type": [
{ "context": "cafe" },
{ "context": "restaurants", "boost": 2 }
]
}
}
}
}
}
コンテキストクエリは、cafe と restaurants カテゴリに関連付けられた提案をフィルタリングし、restaurants に関連付けられた提案を 2 の係数でブーストします。 |
カテゴリ値を受け入れることに加えて、コンテキストクエリは複数のカテゴリコンテキスト条項で構成されることができます。category
コンテキスト条項に対してサポートされている以下のパラメータ:
| | |
| —- | —- |
| context
| フィルタリング/ブーストするカテゴリの値。
これは必須です。 |
| boost
| 提案のスコアをブーストする係数。
スコアはブーストと提案の重みを掛け算して計算され、デフォルトは 1
|
| prefix
| カテゴリ値を接頭辞として扱うかどうか。たとえば、true
に設定されている場合、type1、type2 などのカテゴリをフィルタリングすることができ、type のカテゴリ接頭辞を指定することができます。
デフォルトは false
|
提案エントリが複数のコンテキストに一致する場合、最終スコアは一致するコンテキストの中で生成された最大スコアとして計算されます。
Geo location Context
geo
コンテキストは、インデックス時に提案に1つ以上のジオポイントまたはジオハッシュを関連付けることを可能にします。クエリ時には、提案は特定のジオロケーションからの距離が一定の範囲内にある場合にフィルタリングおよびブーストされることがあります。
内部的に、ジオポイントは指定された精度でジオハッシュとしてエンコードされます。
Geo Mapping
path
設定に加えて、geo
コンテキストマッピングは以下の設定を受け入れます:
precision |
これはインデックスされるジオハッシュの精度を定義し、距離値(5m 、10km など)または生のジオハッシュ精度(1 ..12 )として指定できます。デフォルトは 6 の生のジオハッシュ精度値です。 |
インデックス時の precision
設定は、クエリ時に使用できる最大ジオハッシュ精度を設定します。
Indexing geo contexts
geo
コンテキストは、提案と明示的に設定するか、path
パラメータを介してドキュメント内のジオポイントフィールドからインデックスされることができます。複数のジオロケーションコンテキストを提案に関連付けると、各ジオロケーションのために提案がインデックスされます。以下は、2つのジオロケーションコンテキストで提案をインデックスします:
Python
resp = client.index(
index="place",
id="1",
document={
"suggest": {
"input": "timmy's",
"contexts": {
"location": [
{
"lat": 43.6624803,
"lon": -79.3863353
},
{
"lat": 43.6624718,
"lon": -79.3873227
}
]
}
}
},
)
print(resp)
Ruby
response = client.index(
index: 'place',
id: 1,
body: {
suggest: {
input: "timmy's",
contexts: {
location: [
{
lat: 43.6624803,
lon: -79.3863353
},
{
lat: 43.6624718,
lon: -79.3873227
}
]
}
}
}
)
puts response
Js
const response = await client.index({
index: "place",
id: 1,
document: {
suggest: {
input: "timmy's",
contexts: {
location: [
{
lat: 43.6624803,
lon: -79.3863353,
},
{
lat: 43.6624718,
lon: -79.3873227,
},
],
},
},
},
});
console.log(response);
コンソール
PUT place/_doc/1
{
"suggest": {
"input": "timmy's",
"contexts": {
"location": [
{
"lat": 43.6624803,
"lon": -79.3863353
},
{
"lat": 43.6624718,
"lon": -79.3873227
}
]
}
}
}
Geo location Query
提案は、1つ以上のジオポイントに対してどれだけ近いかに基づいてフィルタリングおよびブーストされることがあります。以下は、ジオポイントのエンコードされたジオハッシュによって表される領域内にある提案をフィルタリングします:
Python
resp = client.search(
index="place",
suggest={
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"location": {
"lat": 43.662,
"lon": -79.38
}
}
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'place',
body: {
suggest: {
place_suggestion: {
prefix: 'tim',
completion: {
field: 'suggest',
size: 10,
contexts: {
location: {
lat: 43.662,
lon: -79.38
}
}
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "place",
suggest: {
place_suggestion: {
prefix: "tim",
completion: {
field: "suggest",
size: 10,
contexts: {
location: {
lat: 43.662,
lon: -79.38,
},
},
},
},
},
});
console.log(response);
Console
POST place/_search
{
"suggest": {
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"location": {
"lat": 43.662,
"lon": -79.380
}
}
}
}
}
}
低い精度のロケーションがクエリ時に指定されると、その領域内にあるすべての提案が考慮されます。
クエリに複数のカテゴリまたはカテゴリコンテキストが設定されている場合、それらは論理和としてマージされます。これは、提案が提供されたコンテキスト値のいずれかを含む場合に一致することを意味します。
ジオハッシュによって表される領域内にある提案は、他の提案よりも高くブーストされることもあります。以下に示すように:
Python
resp = client.search(
index="place",
pretty=True,
suggest={
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"location": [
{
"lat": 43.6624803,
"lon": -79.3863353,
"precision": 2
},
{
"context": {
"lat": 43.6624803,
"lon": -79.3863353
},
"boost": 2
}
]
}
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'place',
pretty: true,
body: {
suggest: {
place_suggestion: {
prefix: 'tim',
completion: {
field: 'suggest',
size: 10,
contexts: {
location: [
{
lat: 43.6624803,
lon: -79.3863353,
precision: 2
},
{
context: {
lat: 43.6624803,
lon: -79.3863353
},
boost: 2
}
]
}
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "place",
pretty: "true",
suggest: {
place_suggestion: {
prefix: "tim",
completion: {
field: "suggest",
size: 10,
contexts: {
location: [
{
lat: 43.6624803,
lon: -79.3863353,
precision: 2,
},
{
context: {
lat: 43.6624803,
lon: -79.3863353,
},
boost: 2,
},
],
},
},
},
},
});
console.log(response);
Console
POST place/_search?pretty
{
"suggest": {
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"location": [
{
"lat": 43.6624803,
"lon": -79.3863353,
"precision": 2
},
{
"context": {
"lat": 43.6624803,
"lon": -79.3863353
},
"boost": 2
}
]
}
}
}
}
}
コンテキストクエリは、ジオロケーションが (43.662, -79.380) のジオハッシュによって表される領域に該当する提案をフィルタリングし、デフォルトの精度 6 で (43.6624803, -79.3863353) のジオハッシュ表現に該当する提案を 2 の係数でブーストします。 |
提案エントリが複数のコンテキストに一致する場合、最終スコアは一致するコンテキストの中で生成された最大スコアとして計算されます。
コンテキスト値を受け入れることに加えて、コンテキストクエリは複数のコンテキスト条項で構成されることができます。geo
コンテキスト条項に対してサポートされている以下のパラメータ:
| | |
| —- | —- |
| context
| フィルタリングまたは提案をブーストするためのジオポイントオブジェクトまたはジオハッシュ文字列。これは必須です。 |
| boost
| 提案のスコアをブーストする係数。
スコアはブーストと提案の重みを掛け算して計算され、デフォルトは 1
|
| precision
| クエリジオポイントをエンコードするためのジオハッシュの精度。
これは距離値(5m
、10km
など)または生のジオハッシュ精度(1
..12
)として指定できます。
デフォルトはインデックス時の精度レベルです。 |
| neighbours
| 隣接するジオハッシュを考慮する精度値の配列を受け入れます。
精度値は距離値(5m
、10km
など)または生のジオハッシュ精度(1
..12
)であることができます。デフォルトはインデックス時の精度レベルの隣接を生成します。 |
精度フィールドは距離一致をもたらしません。10km
のような距離値を指定することは、そのサイズのタイルを表すジオハッシュ精度値をもたらすだけです。精度は、補完一致のために検索ジオポイントをジオハッシュタイルにエンコードするために使用されます。この結果、タイルの外にあるポイントは、検索ポイントに非常に近くても一致しません。精度を下げるか、距離を増やすことで、これが発生するリスクを減らすことができますが、完全に排除することはできません。
Returning the type of the suggester
時には、サジェスターの結果を解析するために、サジェスターの正確なタイプを知る必要があります。typed_keys
パラメータを使用して、応答内でサジェスターの名前を変更し、そのタイプによってプレフィックスを付けることができます。
以下の例では、2つのサジェスター term
と phrase
を考慮します:
Python
resp = client.search(
typed_keys=True,
suggest={
"text": "some test mssage",
"my-first-suggester": {
"term": {
"field": "message"
}
},
"my-second-suggester": {
"phrase": {
"field": "message"
}
}
},
)
print(resp)
Ruby
response = client.search(
typed_keys: true,
body: {
suggest: {
text: 'some test mssage',
"my-first-suggester": {
term: {
field: 'message'
}
},
"my-second-suggester": {
phrase: {
field: 'message'
}
}
}
}
)
puts response
Js
const response = await client.search({
typed_keys: "true",
suggest: {
text: "some test mssage",
"my-first-suggester": {
term: {
field: "message",
},
},
"my-second-suggester": {
phrase: {
field: "message",
},
},
},
});
console.log(response);
Console
POST _search?typed_keys
{
"suggest": {
"text" : "some test mssage",
"my-first-suggester" : {
"term" : {
"field" : "message"
}
},
"my-second-suggester" : {
"phrase" : {
"field" : "message"
}
}
}
}
応答では、サジェスターの名前はそれぞれ term#my-first-suggester
と phrase#my-second-suggester
に変更され、各提案のタイプを反映します:
Console-Result
{
"suggest": {
"term#my-first-suggester": [
{
"text": "some",
"offset": 0,
"length": 4,
"options": []
},
{
"text": "test",
"offset": 5,
"length": 4,
"options": []
},
{
"text": "mssage",
"offset": 10,
"length": 6,
"options": [
{
"text": "message",
"score": 0.8333333,
"freq": 4
}
]
}
],
"phrase#my-second-suggester": [
{
"text": "some test mssage",
"offset": 0,
"length": 16,
"options": [
{
"text": "some test message",
"score": 0.030227963
}
]
}
]
},
...
}
名前 my-first-suggester は現在 term プレフィックスを含んでいます。 |
|
名前 my-second-suggester は現在 phrase プレフィックスを含んでいます。 |