2013-03-15 25 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"}' 

我想爲「約翰·史密斯」搜索只匹配文件1.下面的查詢做什麼,我需要,但我寧願避免使用QUERY_STRING的情況下,用戶通過「OR」,「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

我不停地一遍又一遍地回答這個問題。偉大的常青樹問題! – 2013-11-09 00:53:55

回答

23

您正在尋找的是multi-match query,但它的表現並不盡如人意。

multi_matchquery_string比較validate的輸出。

multi_match(與運營商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 
# } 

雖然query_string(與default_operator AND)將檢查每學期至少在一個領域存在:

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查詢您的映射名稱字段以將其數據索引到單個字段中,然後可以將其用於搜索。 (如您的自定義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

你可以使用multi-fieldspath參數,使其搜索這兩個獨立和在一起,如下所示:

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沒有按」 t工作:

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正常工作:

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

相關問題