Elasticsearch学習ノート上級編(十一)-マルチフィールド検索(下)
11008 ワード
前のブログを引き継ぐhttps://segmentfault.com/a/11...
most_fieldsはフィールドを中心としており、最も一致するフィールドをクエリーします.ユーザーにアドレスを検索させるものがあるとします.次の2つのドキュメントがあります.
most_の使用fieldsによるクエリー:
各フィールドに対してクエリー文字列を繰り返すとすぐに冗長になりmulti_matchは以下のように簡略化される.
結果:
best_を使うとfields、doc 2はdoc 1の前にあります
結果:
(1)すべてのフィールドにまたがる最も一致する単語を見つけるのではなく、任意の単語に一致する多数のフィールドを見つけるように設計されています(2)operatorまたはminimum_を使用できません.should_matchパラメータは,低相関結果による長尾効果を低減するために用いられる(3)各フィールドの語条頻度が異なり,互いに干渉し,最終的に劣る並べ替え結果を得る.
most_と言いましたFieldsの問題は、次はこの問題を解決します.この問題を解決する最初の方法はcopyを使うことです.toパラメータ.copyを使ってto複数のfieldを1つのfieldに組み合わせて、次のインデックスを作成します.
前のデータを挿入:
クエリー:
結果:
フィールドfullになることがわかりますaddressの後、most_を解決できます.fieldsの問題です.
解決するfieldsの問題の2つ目の方法はcross_を使用することですfieldsクエリー.ドキュメントをインデックスする前に使用できる場合はallまたはcopyを事前に定義します.toなら、大丈夫です.しかし、Elasticsearchはcross_を使用する検索期間のソリューションも提供しています.fieldsクエリー.cross_fieldsは単語を中心とした方法を採用し,best_とfieldsおよびmost_fieldsが採用するフィールド中心の方法には大きな違いがある.すべてのフィールドを大きなフィールドと見なし、任意のフィールドで各単語を検索します.フィールド中心と見出し語中心の違いを説明します.
クエリーを使用:
取得:
(postcode:poland postcode:street postcode:w 1 v)|(country:poland country:street country:w 1 v)|(city:poland city:street city:w 1 v)|(street:poland street:street:w 1 v))これがルールです.operatorをandに設定すると(((+postcode:poland+postcode:street+postcode:w 1 v)|(+country:poland+country:street+country:w 1 v)|(+city:poland+city:street+city:w 1 v)|(+street:poland+street:street:street+street:w 1 v))4つの単語が同じフィールドに表示される必要があることを示します.
クエリーによる
取得:
+blended(terms:[postcode:poland,country:poland,city:poland,street:poland])+blended(terms:[postcode:street,country:street,city:street,street:street])+blended(terms:[postcode:w 1 v,country:w 1 v,city:w 1 v,street:w 1 v])これがルールです.言い換えれば、すべての語は任意のフィールドに表示されなければならない.cross_fieldsタイプでは、まずクエリー文字列を解析して単語リストを取得し、任意のフィールドで各単語を検索します.フィールドのバックグラウンドドキュメント頻度をブレンドすることで、単語頻度の問題を解決します.それで完璧な結末になったmost_fieldsの問題.cross_の使用fieldsはcopy_よりtoは、クエリ中に個別フィールドを重み付けすることができる.例:
これによりstreetフィールドのboostは2であり、他のフィールドは1である.
4、most_fieldsクエリー
most_fieldsはフィールドを中心としており、最も一致するフィールドをクエリーします.ユーザーにアドレスを検索させるものがあるとします.次の2つのドキュメントがあります.
PUT /test_index/_create/1
{
"street": "5 Poland Street",
"city": "Poland",
"country": "United W1V",
"postcode": "W1V 3DG"
}
PUT /test_index/_create/2
{
"street": "5 Poland Street W1V",
"city": "London",
"country": "United Kingdom",
"postcode": "3DG"
}
most_の使用fieldsによるクエリー:
GET /test_index/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"street": "Poland Street W1V"
}
},
{
"match": {
"city": "Poland Street W1V"
}
},
{
"match": {
"country": "Poland Street W1V"
}
},
{
"match": {
"postcode": "Poland Street W1V"
}
}
]
}
}
}
各フィールドに対してクエリー文字列を繰り返すとすぐに冗長になりmulti_matchは以下のように簡略化される.
GET /test_index/_search
{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "most_fields",
"fields": ["street", "city", "country", "postcode"]
}
}
}
結果:
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 2.3835402,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 2.3835402,
"_source" : {
"street" : "5 Poland Street",
"city" : "Poland",
"country" : "United W1V",
"postcode" : "W1V 3DG"
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.99938464,
"_source" : {
"street" : "5 Poland Street W1V",
"city" : "London",
"country" : "United Kingdom",
"postcode" : "3DG"
}
}
]
}
}
best_を使うとfields、doc 2はdoc 1の前にあります
GET /test_index/_search
{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "best_fields",
"fields": ["street", "city", "country", "postcode"]
}
}
}
結果:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.99938464,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.99938464,
"_source" : {
"street" : "5 Poland Street W1V",
"city" : "London",
"country" : "United Kingdom",
"postcode" : "3DG"
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.6931472,
"_source" : {
"street" : "5 Poland Street",
"city" : "Poland",
"country" : "United W1V",
"postcode" : "W1V 3DG"
}
}
]
}
}
most_の使用フィールドに存在する問題
(1)すべてのフィールドにまたがる最も一致する単語を見つけるのではなく、任意の単語に一致する多数のフィールドを見つけるように設計されています(2)operatorまたはminimum_を使用できません.should_matchパラメータは,低相関結果による長尾効果を低減するために用いられる(3)各フィールドの語条頻度が異なり,互いに干渉し,最終的に劣る並べ替え結果を得る.
5、全フィールドクエリーcopy_を使用するtoパラメータ
most_と言いましたFieldsの問題は、次はこの問題を解決します.この問題を解決する最初の方法はcopyを使うことです.toパラメータ.copyを使ってto複数のfieldを1つのfieldに組み合わせて、次のインデックスを作成します.
DELETE /test_index
PUT /test_index
{
"mappings": {
"properties": {
"street": {
"type": "text",
"copy_to": "full_address"
},
"city": {
"type": "text",
"copy_to": "full_address"
},
"country": {
"type": "text",
"copy_to": "full_address"
},
"postcode": {
"type": "text",
"copy_to": "full_address"
},
"full_address": {
"type": "text"
}
}
}
}
前のデータを挿入:
PUT /test_index/_create/1
{
"street": "5 Poland Street",
"city": "Poland",
"country": "United W1V",
"postcode": "W1V 3DG"
}
PUT /test_index/_create/2
{
"street": "5 Poland Street W1V",
"city": "London",
"country": "United Kingdom",
"postcode": "3DG"
}
クエリー:
GET /test_index/_search
{
"query": {
"match": {
"full_address": "Poland Street W1V"
}
}
}
結果:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.68370587,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.68370587,
"_source" : {
"street" : "5 Poland Street",
"city" : "Poland",
"country" : "United W1V",
"postcode" : "W1V 3DG"
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.5469647,
"_source" : {
"street" : "5 Poland Street W1V",
"city" : "London",
"country" : "United Kingdom",
"postcode" : "3DG"
}
}
]
}
}
フィールドfullになることがわかりますaddressの後、most_を解決できます.fieldsの問題です.
5、cross_fieldsクエリー
解決するfieldsの問題の2つ目の方法はcross_を使用することですfieldsクエリー.ドキュメントをインデックスする前に使用できる場合はallまたはcopyを事前に定義します.toなら、大丈夫です.しかし、Elasticsearchはcross_を使用する検索期間のソリューションも提供しています.fieldsクエリー.cross_fieldsは単語を中心とした方法を採用し,best_とfieldsおよびmost_fieldsが採用するフィールド中心の方法には大きな違いがある.すべてのフィールドを大きなフィールドと見なし、任意のフィールドで各単語を検索します.フィールド中心と見出し語中心の違いを説明します.
フィールド中心
クエリーを使用:
GET /test_index/_validate/query?explain
{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "best_fields",
"fields": ["street", "city", "country", "postcode"]
}
}
}
取得:
{
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"valid" : true,
"explanations" : [
{
"index" : "test_index",
"valid" : true,
"explanation" : "((postcode:poland postcode:street postcode:w1v) | (country:poland country:street country:w1v) | (city:poland city:street city:w1v) | (street:poland street:street street:w1v))"
}
]
}
(postcode:poland postcode:street postcode:w 1 v)|(country:poland country:street country:w 1 v)|(city:poland city:street city:w 1 v)|(street:poland street:street:w 1 v))これがルールです.operatorをandに設定すると(((+postcode:poland+postcode:street+postcode:w 1 v)|(+country:poland+country:street+country:w 1 v)|(+city:poland+city:street+city:w 1 v)|(+street:poland+street:street:street+street:w 1 v))4つの単語が同じフィールドに表示される必要があることを示します.
単語中心
クエリーによる
GET /test_index/_validate/query?explain
{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "cross_fields",
"operator": "and",
"fields": ["street", "city", "country", "postcode"]
}
}
}
取得:
{
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"valid" : true,
"explanations" : [
{
"index" : "test_index",
"valid" : true,
"explanation" : "+blended(terms:[postcode:poland, country:poland, city:poland, street:poland]) +blended(terms:[postcode:street, country:street, city:street, street:street]) +blended(terms:[postcode:w1v, country:w1v, city:w1v, street:w1v])"
}
]
}
+blended(terms:[postcode:poland,country:poland,city:poland,street:poland])+blended(terms:[postcode:street,country:street,city:street,street:street])+blended(terms:[postcode:w 1 v,country:w 1 v,city:w 1 v,street:w 1 v])これがルールです.言い換えれば、すべての語は任意のフィールドに表示されなければならない.cross_fieldsタイプでは、まずクエリー文字列を解析して単語リストを取得し、任意のフィールドで各単語を検索します.フィールドのバックグラウンドドキュメント頻度をブレンドすることで、単語頻度の問題を解決します.それで完璧な結末になったmost_fieldsの問題.cross_の使用fieldsはcopy_よりtoは、クエリ中に個別フィールドを重み付けすることができる.例:
GET /test_index/_search
{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "cross_fields",
"fields": ["street^2", "city", "country", "postcode"]
}
}
}
これによりstreetフィールドのboostは2であり、他のフィールドは1である.