elasticsearch之单请求多查询

一、需要解决的问题

有的时候我们需要同时执行多个查询,并且需要得到每个单独查询的搜索结果,elasticsearch提供了multi search此需求的支持;

二、elasticsearch multi search简介

elasticsearch提供了multi search api来支持一个请求执行多个查询;

multi search api的请求体使用换行分割的JSON格式;

headern bodyn headern bodyn 

multi search返回的结果是responses数组,每个查询对应一个数组元素;每个数组元素都有一个status字段指示查询是否执行成功,如果执行失败则error字段返回错误信息;

每个查询可以通过自己的header设置查询执行的index,也可以是空的JSON对象,这是在URL中指定的index执行查询;

三、数据准备

index以下四个文档

PUT /multi_test/_doc/1 { 	"name":"Google Chrome" }   PUT /multi_test/_doc/2 { 	"name":"NotePad" }  PUT /multi_test/_doc/3 { 	"name":"Word" }  PUT /multi_test/_doc/4 { 	"name":"PyCharm" } 

查询查看已经索引的数据

GET /multi_test/_search  {     "took":0,     "timed_out":false,     "_shards":{         "total":5,         "successful":5,         "skipped":0,         "failed":0     },     "hits":{         "total":4,         "max_score":1,         "hits":[             {                 "_index":"multi_test",                 "_type":"_doc",                 "_id":"2",                 "_score":1,                 "_source":{                     "name":"NotePad"                 }             },             {                 "_index":"multi_test",                 "_type":"_doc",                 "_id":"4",                 "_score":1,                 "_source":{                     "name":"PyCharm"                 }             },             {                 "_index":"multi_test",                 "_type":"_doc",                 "_id":"1",                 "_score":1,                 "_source":{                     "name":"Google Chrome"                 }             },             {                 "_index":"multi_test",                 "_type":"_doc",                 "_id":"3",                 "_score":1,                 "_source":{                     "name":"Word"                 }             }         ]     } } 

四、查询测试

我们构造以下四个查询同时执行

POST /multi_test/_msearch  {} {"query":{"match":{"name":"google"}}} {} {"query":{"match":{"name":"nohit"}}} {} {"query":{"match":{"name":"word"}}} {} {"query":{"bool":{"should":[{"match":{"name":"word"}}, {"match":{"name":"pycharm"}}]}}} 

我们可以看到不管查询是否命中结果,都会有一个responses数组元素对应;同时responses数组元素的顺序与查询是一 一对应的;

{     "responses":[         {             "took":0,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":1,                 "max_score":0.2876821,                 "hits":[                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"1",                         "_score":0.2876821,                         "_source":{                             "name":"Google Chrome"                         }                     }                 ]             },             "status":200         },         {             "took":0,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":0,                 "max_score":null,                 "hits":[                  ]             },             "status":200         },         {             "took":0,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":1,                 "max_score":0.2876821,                 "hits":[                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"3",                         "_score":0.2876821,                         "_source":{                             "name":"Word"                         }                     }                 ]             },             "status":200         },         {             "took":0,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":2,                 "max_score":0.6931472,                 "hits":[                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"4",                         "_score":0.6931472,                         "_source":{                             "name":"PyCharm"                         }                     },                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"3",                         "_score":0.2876821,                         "_source":{                             "name":"Word"                         }                     }                 ]             },             "status":200         }     ] } 

五、multi search对search template的支持

multi search api也支持search template;

muti search内联search template查询

POST /multi_test/_msearch/template {} { "source" : "{ "query": { "match": { "name" : "{{name}}" } } } }", "params": { "name": "google" } } {} { "source" : "{ "query": { "match_{{template}}": {} } }", "params": { "template": "all" } }  

查询结果为

{     "responses":[         {             "took":0,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":1,                 "max_score":0.2876821,                 "hits":[                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"1",                         "_score":0.2876821,                         "_source":{                             "name":"Google Chrome"                         }                     }                 ]             }         },         {             "took":8,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":4,                 "max_score":1,                 "hits":[                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"2",                         "_score":1,                         "_source":{                             "name":"NotePad"                         }                     },                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"4",                         "_score":1,                         "_source":{                             "name":"PyCharm"                         }                     },                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"1",                         "_score":1,                         "_source":{                             "name":"Google Chrome"                         }                     },                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"3",                         "_score":1,                         "_source":{                             "name":"Word"                         }                     }                 ]             }         }     ] } 

也可以直接新建search template

POST /_scripts/multi_test_name_template/  {     "script":{         "lang":"mustache",         "source":{             "query":{                 "bool":{                     "should":[                         {                             "match":{                                 "name":"{{name}}"                             }                         },                         {                             "wildcard":{                                 "name":"*{{name}}*"                             }                         }                     ]                 }             }         }     } } 

使用新建的search template进行搜索

POST /multi_test/_msearch/template {} { "id": "multi_test_name_template", "params": { "name": "oo" } } {} { "id": "multi_test_name_template", "params": { "name": "notepad" } } 

搜索结果如下

{     "responses":[         {             "took":1,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":1,                 "max_score":1,                 "hits":[                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"1",                         "_score":1,                         "_source":{                             "name":"Google Chrome"                         }                     }                 ]             }         },         {             "took":1,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":1,                 "max_score":1.6931472,                 "hits":[                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"2",                         "_score":1.6931472,                         "_source":{                             "name":"NotePad"                         }                     }                 ]             }         }     ] } 

在search template中使用嵌套字段作为参数

POST /multi_test/_msearch/template {} { "source" : "{ "query": { "match": { "name" : "{{person.name}}" } } } }", "params": { "person":{"name": "google"} } }  

搜索结果如下

{     "responses":[         {             "took":3,             "timed_out":false,             "_shards":{                 "total":5,                 "successful":5,                 "skipped":0,                 "failed":0             },             "hits":{                 "total":1,                 "max_score":0.2876821,                 "hits":[                     {                         "_index":"multi_test",                         "_type":"_doc",                         "_id":"1",                         "_score":0.2876821,                         "_source":{                             "name":"Google Chrome"                         }                     }                 ]             }         }     ] } 

发表评论

相关文章