22

複数の単語の検索を、検索されたすべての単語が任意のフィールド、任意の組み合わせに含まれている複数のフィールドと照合できるようにしたいと思います。キャッチは、 query_stringの使用を避けたいということです。

curl -X POST "http://localhost:9200/index/document/1" -d '{"id":1,"firstname":"john","middlename":"clark","lastname":"smith"}'
curl -X POST "http://localhost:9200/index/document/2" -d '{"id":2,"firstname":"john","middlename":"paladini","lastname":"miranda"}'

「JohnSmith」の検索をドキュメント1のみに一致させたいのですが、次のクエリは必要なことを実行しますが、ユーザーが「OR」、「AND」、およびその他の高度なパラメータを渡した場合に備えて、query_stringの使用は避けたいと思います。

curl -X GET 'http://localhost:9200/index/_search?per_page=10&pretty' -d '{
  "query": {
    "query_string": {
      "query": "john smith",
      "default_operator": "AND",
      "fields": [
        "firstname",
        "lastname",
        "middlename"
      ]
    }
  }
}'
4

4 に答える 4

35

探しているのはマルチマッチクエリですが、期待どおりに機能しません。

との検証multi_match出力を比較しますquery_string

multi_match(演算子andを使用)は、すべての用語が少なくとも1つのフィールドに存在することを確認します。

curl -XGET 'http://127.0.0.1:9200/_validate/query?pretty=1&explain=true'  -d '
{
   "multi_match" : {
      "operator" : "and",
      "fields" : [
         "firstname",
         "lastname"
      ],
      "query" : "john smith"
   }
}
'

# {
#    "_shards" : {
#       "failed" : 0,
#       "successful" : 1,
#       "total" : 1
#    },
#    "explanations" : [
#       {
#          "index" : "test",
#          "explanation" : "((+lastname:john +lastname:smith) | (+firstname:john +firstname:smith))",
#          "valid" : true
#       }
#    ],
#    "valid" : true
# }

一方query_string(default_operatorANDを使用)は、各用語が少なくとも1つのフィールドに存在することを確認します。

curl -XGET 'http://127.0.0.1:9200/_validate/query?pretty=1&explain=true'  -d '
{
   "query_string" : {
      "fields" : [
         "firstname",
         "lastname"
      ],
      "query" : "john smith",
      "default_operator" : "AND"
   }
}
'

# {
#    "_shards" : {
#       "failed" : 0,
#       "successful" : 1,
#       "total" : 1
#    },
#    "explanations" : [
#       {
#          "index" : "test",
#          "explanation" : "+(firstname:john | lastname:john) +(firstname:smith | lastname:smith)",
#          "valid" : true
#       }
#    ],
#    "valid" : true
# }

したがって、あなたはあなたが求めているものを達成するためにいくつかの選択肢があります:

  1. を使用する前に、検索語を事前に解析して、ワイルドカードなどを削除します。query_string

  2. 検索語を事前解析して各単語を抽出し、単語ごとにmulti_matchクエリを生成します

  3. 名前フィールドのマッピングで使用index_nameして、データを単一のフィールドにインデックス付けし、検索に使用できます。(独自のカスタムallフィールドのように):

次のように:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '
{
   "mappings" : {
      "test" : {
         "properties" : {
            "firstname" : {
               "index_name" : "name",
               "type" : "string"
            },
            "lastname" : {
               "index_name" : "name",
               "type" : "string"
            }
         }
      }
   }
}
'

curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1'  -d '
{
   "firstname" : "john",
   "lastname" : "smith"
}
'

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "match" : {
         "name" : {
            "operator" : "and",
            "query" : "john smith"
         }
      }
   }
}
'

# {
#    "hits" : {
#       "hits" : [
#          {
#             "_source" : {
#                "firstname" : "john",
#                "lastname" : "smith"
#             },
#             "_score" : 0.2712221,
#             "_index" : "test",
#             "_id" : "VJFU_RWbRNaeHF9wNM8fRA",
#             "_type" : "test"
#          }
#       ],
#       "max_score" : 0.2712221,
#       "total" : 1
#    },
#    "timed_out" : false,
#    "_shards" : {
#       "failed" : 0,
#       "successful" : 5,
#       "total" : 5
#    },
#    "took" : 33
# }

ただし、firstnamelastnameは独立して検索できなくなったことに注意してください。両方のフィールドのデータはにインデックス付けされていますname

次のように、パラメータでマルチフィールドを使用pathして、独立して、または一緒に検索できるようにすることができます。

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '
{
   "mappings" : {
      "test" : {
         "properties" : {
            "firstname" : {
               "fields" : {
                  "firstname" : {
                     "type" : "string"
                  },
                  "any_name" : {
                     "type" : "string"
                  }
               },
               "path" : "just_name",
               "type" : "multi_field"
            },
            "lastname" : {
               "fields" : {
                  "any_name" : {
                     "type" : "string"
                  },
                  "lastname" : {
                     "type" : "string"
                  }
               },
               "path" : "just_name",
               "type" : "multi_field"
            }
         }
      }
   }
}
'

curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1'  -d '
{
   "firstname" : "john",
   "lastname" : "smith"
}
'

any_nameフィールドの検索は機能します:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "match" : {
         "any_name" : {
            "operator" : "and",
            "query" : "john smith"
         }
      }
   }
}
'

# {
#    "hits" : {
#       "hits" : [
#          {
#             "_source" : {
#                "firstname" : "john",
#                "lastname" : "smith"
#             },
#             "_score" : 0.2712221,
#             "_index" : "test",
#             "_id" : "Xf9qqKt0TpCuyLWioNh-iQ",
#             "_type" : "test"
#          }
#       ],
#       "max_score" : 0.2712221,
#       "total" : 1
#    },
#    "timed_out" : false,
#    "_shards" : {
#       "failed" : 0,
#       "successful" : 5,
#       "total" : 5
#    },
#    "took" : 11
# }

検索firstnamejohn AND smith機能しません:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "match" : {
         "firstname" : {
            "operator" : "and",
            "query" : "john smith"
         }
      }
   }
}
'

# {
#    "hits" : {
#       "hits" : [],
#       "max_score" : null,
#       "total" : 0
#    },
#    "timed_out" : false,
#    "_shards" : {
#       "failed" : 0,
#       "successful" : 5,
#       "total" : 5
#    },
#    "took" : 2
# }

しかし、検索firstnamejohn正しく機能します。

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "match" : {
         "firstname" : {
            "operator" : "and",
            "query" : "john"
         }
      }
   }
}
'

# {
#    "hits" : {
#       "hits" : [
#          {
#             "_source" : {
#                "firstname" : "john",
#                "lastname" : "smith"
#             },
#             "_score" : 0.30685282,
#             "_index" : "test",
#             "_id" : "Xf9qqKt0TpCuyLWioNh-iQ",
#             "_type" : "test"
#          }
#       ],
#       "max_score" : 0.30685282,
#       "total" : 1
#    },
#    "timed_out" : false,
#    "_shards" : {
#       "failed" : 0,
#       "successful" : 5,
#       "total" : 5
#    },
#    "took" : 3
# }
于 2013-03-15T10:40:42.167 に答える
1

ユーザーが「OR」、「AND」、およびその他の高度なパラメーターを渡す場合に備えて、query_stringの使用は避けたいと思います。

私の経験では、バックスラッシュを使用して特殊文字をエスケープすることは、単純で効果的な解決策です。このリストは、ドキュメントhttp://lucene.apache.org/core/4_5_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package_descriptionに加えて、AND / OR / NOT/TOにあります。 。

于 2013-12-06T20:06:18.903 に答える
0

最近では、 cross_fieldsタイプを使用できますmulti_match

GET /_validate/query?explain
{
    "query": {
        "multi_match": {
            "query":       "peter smith",
            "type":        "cross_fields", 
            "operator":    "and",
            "fields":      [ "firstname", "lastname", "middlename" ]
        }
    }
}

クロスフィールドは、用語中心のアプローチを取ります。すべてのフィールドを1つの大きなフィールドとして扱い、任意のフィールドの各用語を検索します。

ただし、最適に機能させるには、分析するすべてのフィールドに同じアナライザー(標準、英語など)を使用する必要があることに注意してください。

cross_fieldsクエリタイプが最適に機能するには、すべてのフィールドに同じアナライザーが必要です。アナライザーを共有するフィールドは、混合フィールドとしてグループ化されます。

分析チェーンが異なるフィールドを含めると、best_fieldsの場合と同じ方法でクエリに追加されます。たとえば、前のクエリにタイトルフィールドを追加した場合(別のアナライザーを使用していると仮定)、説明は次のようになります。

(+ title:peter + title:smith)(+ blended( "peter"、fields:[first_name、last_name])+ blended( "smith"、fields:[first_name、last_name]))

于 2019-04-12T15:11:37.750 に答える
-1

「一致」クエリはあなたが探しているものだと思います:

「クエリの一致ファミリは「クエリ解析」プロセスを通過しません。フィールド名のプレフィックス、ワイルドカード文字、またはその他の「高度な」機能をサポートしていません。このため、失敗する可能性は非常に小さい/存在しません。そして、そのテキストをクエリ動作として分析して実行する場合に優れた動作を提供します(これは通常、テキスト検索ボックスが行うことです)。」

http://www.elasticsearch.org/guide/reference/query-dsl/match-query.html

于 2013-03-15T07:47:22.307 に答える