我希望能够将多个单词搜索与多个字段匹配,其中每个搜索的单词都包含在 任何 字段,任何组合中。问题是我想 避免使用 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"}'
我希望搜索“ John Smith”以仅匹配文档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" ] } } }'
您正在寻找的是多重匹配查询,但是它的执行效果并不理想。
比较器的输出验证了multi_matchVS query_string。
multi_match
query_string
multi_match(与operator一起使用and)将确保所有术语都存在于至少一个字段中:
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(with default_operator AND)将检查EACH术语是否存在于至少一个字段中:
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 # }
因此,您有几种选择可以实现自己的目标:
在使用搜索引擎之前,请准备好搜索字词,以删除通配符等内容。 query_string
准备搜索词以提取每个单词,然后为每个单词生成multi_match查询
使用index_name您的映射名称字段来索引他们的数据到一个单一的领域,然后你就可以使用搜索。(例如您自己的自定义all字段):
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 # }
但是请注意,firstname并且lastname不再可以独立搜索。这两个字段的数据都已索引到中name。
firstname
lastname
name
您可以将multifields与path参数一起使用,以使它们既可以独立搜索也可以一起搜索,如下所示:
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现场作品:
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 # }
搜索firstname为john AND smith不工作:
john 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 # }
但是搜索firstname仅能john正常工作:
john
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 # }