6

elasticsearch之单请求多查询 - 无风听海

 1 year ago
source link: https://www.cnblogs.com/wufengtinghai/p/17028555.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

elasticsearch之单请求多查询

一、需要解决的问题

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

二、elasticsearch multi search简介

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

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

header\n
body\n
header\n
body\n

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"
                        }
                    }
                ]
            }
        }
    ]
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK