2013-03-15 12 views
12

複数のフィールドに対して複数単語の検索を一致させたいのですが、すべての単語がフィールドのいずれかのの任意の組み合わせに含まれています。キャッチは私が query_stringの使用を避けたいです。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"}' 

私は次のクエリは、何が必要ありませんが、私はむしろ、ユーザーパス「OR」の場合にはQUERY_STRINGを使用して回避する唯一の文書1を一致させるために「ジョン・スミス」を検索したい場合は、「AND」と他の高度なパラメータのいずれか。

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" 
     ] 
    } 
    } 
}' 
+0

私は何度も何度もこの疑問に遭い続けています。偉大な、常緑樹の質問! –

答えて

23

あなたが探しているものはmulti-match queryですが、それはあなたが望むような方法では動作しません。

query_stringの出力をvalidateと比較してください。 query_string(default_operator ANDとは)各用語は、少なくとも一つのフィールドに存在することを確認しますが

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 
# } 

:(オペレーターand付き)

multi_matchは、すべての用語は、少なくとも一つのフィールドに存在することを確認します

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. Preparse検索用語は、それぞれの単語を抽出するためにquery_string

  2. Preparseに検索用語を使用する前に、などのワイルドカード、のようなものを削除するには、その後のワード

  3. 使用index_nameあたりmulti_matchクエリを生成し、あなたの名前フィールドをマッピングしてデータを1つのフィールドにインデックス付けし、検索に使用することができます。 (独自のカスタム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パラメータでmulti-fieldsを使用することができます。

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 
# } 

をdoesnのjohn AND smith」のfirstnameを検索仕事:

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 
# } 

しかし、正しくちょうどjohn作品のfirstname検索:ユーザーが合格 "OR"、 "AND" およびその他の高度のparamsのいずれかの場合には、私はむしろ、QUERY_STRINGを使用して回避する

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 
# } 
0

私が「一致」のクエリはあなたが探しているものだと思う:。クエリの解析 『プロセス「クエリのマッチ家族が通過しない』

これは、フィールド名のプレフィックスをサポートしていません、ワイルドカード文字やその他の「先進的な」機能を使用することができます。このため、失敗する可能性は非常に小さく、また存在しないため、クエリの動作としてテキストを分析して実行する際に優れた動作を提供します。テキスト検索ボックス) "

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

関連する問題