5

elasticsearch之search template - 无风听海

 1 year ago
source link: https://www.cnblogs.com/wufengtinghai/p/17061029.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之search template

一、search template简介

elasticsearch提供了search template功能,其会在实际执行查询之前,对search template进行预处理并将参数填充到template中。

elasticsearch主要提供了两个API来支持search template
_scripts/用于对search template的维护;
_search/template使用search template进行搜索;

二、测试数据准备

批量index三个文档

POST _bulk

{ "index" : { "_index" : "search_template_test", "_type" : "_doc", "_id" : "1" } }
{ "name":"zhang san",	"age":30,	"man":true,	"address":"Hebei LangFang"}
{ "index" : { "_index" : "search_template_test", "_type" : "_doc", "_id" : "2" } }
{ "name":"li si",	"age":20,	"man":true,	"address":"BeiJing HaiDian"}
{ "index" : { "_index" : "search_template_test", "_type" : "_doc", "_id" : "3" } }
{ "name":"liu hui",	"age":40,	"man":false,	"address":"NeiMengGu ChiFeng"}


查询查看三个索引的文档

GET search_template_test/_search
{
    "took":6,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":3,
        "max_score":1,
        "hits":[
            {
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"2",
                "_score":1,
                "_source":{
                    "name":"li si",
                    "age":20,
                    "man":true,
                    "address":"BeiJing HaiDian"
                }
            },
            {
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"1",
                "_score":1,
                "_source":{
                    "name":"zhang san",
                    "age":30,
                    "man":true,
                    "address":"Hebei LangFang"
                }
            },
            {
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"3",
                "_score":1,
                "_source":{
                    "name":"liu hui",
                    "age":40,
                    "man":false,
                    "address":"NeiMengGu ChiFeng"
                }
            }
        ]
    }
}

三、维护search template

我们新建id为search_template_test.match_name的search template,其主要是查询match 字段name;

POST _scripts/search_template_test.match_name
{
    "script": {        
        "lang": "mustache",
        "source": {
            "query": {
                "match": {
                    "name": "{{name_val}}"
                }
            }
        }
    }
}

查看我们创建的search template

GET _scripts/search_template_test.match_name

{
    "_id":"search_template_test.match_name",
    "found":true,
    "script":{
        "lang":"mustache",
        "source":"{\"query\":{\"match\":{\"name\":\"{{name_val}}\"}}}",
        "options":{
            "content_type":"application/json; charset=UTF-8"
        }
    }
}

删除我们创建的search template

DELET _scripts/search_template_test.match_name
{
    "acknowledged":true
}

elasticsearch提供了API支持我们查看预处理最终形成的查询语句;

POST _render/template/search_template_test.match_name
{
    "params":{
        "name_val":"zhang li"
    }
}


{
    "template_output":{
        "query":{
            "match":{
                "name":"zhang li"
            }
        }
    }
}

四、使用search template

我们可以像下边这样使用search template

POST search_template_test/_search/template
{
    "id": "search_template_test.match_name", 
    "params": {
        "name_val":"zhang li"
    }
}



{
    "took":1,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":2,
        "max_score":0.2876821,
        "hits":[
            {
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"2",
                "_score":0.2876821,
                "_source":{
                    "name":"li si",
                    "age":20,
                    "man":true,
                    "address":"BeiJing HaiDian"
                }
            },
            {
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"1",
                "_score":0.2876821,
                "_source":{
                    "name":"zhang san",
                    "age":30,
                    "man":true,
                    "address":"Hebei LangFang"
                }
            }
        ]
    }
}

执行search template也支持使用explain来调试查看elasticsearch的打分情况;

POST search_template_test/_search/template
{
    "id": "search_template_test.match_name", 
    "params": {
        "name_val":"zhang li"
    },
    "explain":true
}




{
    "took":3,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":2,
        "max_score":0.2876821,
        "hits":[
            {
                "_shard":"[search_template_test][2]",
                "_node":"Sl6S4Kn2Rh-BdNgaM3ZwJg",
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"2",
                "_score":0.2876821,
                "_source":{
                    "name":"li si",
                    "age":20,
                    "man":true,
                    "address":"BeiJing HaiDian"
                },
                "_explanation":{
                    "value":0.2876821,
                    "description":"sum of:",
                    "details":[
                        {
                            "value":0.2876821,
                            "description":"weight(name:li in 0) [PerFieldSimilarity], result of:",
                            "details":[
                                ......
                            ]
                        }
                    ]
                }
            },
            {
                "_shard":"[search_template_test][3]",
                "_node":"Sl6S4Kn2Rh-BdNgaM3ZwJg",
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"1",
                "_score":0.2876821,
                "_source":{
                    "name":"zhang san",
                    "age":30,
                    "man":true,
                    "address":"Hebei LangFang"
                },
                "_explanation":{
                    "value":0.2876821,
                    "description":"sum of:",
                    "details":[
                        {
                            "value":0.2876821,
                            "description":"weight(name:zhang in 0) [PerFieldSimilarity], result of:",
                            "details":[
                                ......
                            ]
                        }
                    ]
                }
            }
        ]
    }
}

执行search template也支持使用profile来调试查看elasticsearch的查询执行情况;

POST search_template_test/_search/template
{
    "id": "search_template_test.match_name", 
    "params": {
        "name_val":"zhang li"
    },
    "profile":true
}



{
    "took":11,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":2,
        "max_score":0.2876821,
        "hits":[

        ]
    },
    "profile":{
        "shards":[
            {
                "id":"[Sl6S4Kn2Rh-BdNgaM3ZwJg][search_template_test][0]",
                "searches":[
                    {
                        "query":[
                            {
                                "type":"BooleanQuery",
                                "description":"name:zhang name:li",
                                "time_in_nanos":308301,
                                "breakdown":{
                                    "score":0,
                                    "build_scorer_count":0,
                                    "match_count":0,
                                    "create_weight":308300,
                                    "next_doc":0,
                                    "match":0,
                                    "create_weight_count":1,
                                    "next_doc_count":0,
                                    "score_count":0,
                                    "build_scorer":0,
                                    "advance":0,
                                    "advance_count":0
                                },
                                "children":[
                                    {
                                        "type":"TermQuery",
                                        "description":"name:zhang",
                                        "time_in_nanos":32901,
                                        "breakdown":{
                                            "score":0,
                                            "build_scorer_count":0,
                                            "match_count":0,
                                            "create_weight":32900,
                                            "next_doc":0,
                                            "match":0,
                                            "create_weight_count":1,
                                            "next_doc_count":0,
                                            "score_count":0,
                                            "build_scorer":0,
                                            "advance":0,
                                            "advance_count":0
                                        }
                                    },
                                    {
                                        "type":"TermQuery",
                                        "description":"name:li",
                                        "time_in_nanos":15901,
                                        "breakdown":{
                                            "score":0,
                                            "build_scorer_count":0,
                                            "match_count":0,
                                            "create_weight":15900,
                                            "next_doc":0,
                                            "match":0,
                                            "create_weight_count":1,
                                            "next_doc_count":0,
                                            "score_count":0,
                                            "build_scorer":0,
                                            "advance":0,
                                            "advance_count":0
                                        }
                                    }
                                ]
                            }
                        ],
                        "rewrite_time":42700,
                        "collector":[
                            {
                                "name":"CancellableCollector",
                                "reason":"search_cancelled",
                                "time_in_nanos":700,
                                "children":[
                                    {
                                        "name":"SimpleTopScoreDocCollector",
                                        "reason":"search_top_hits",
                                        "time_in_nanos":200
                                    }
                                ]
                            }
                        ]
                    }
                ],
                "aggregations":[

                ]
            }
        ]
    }
}

五、使用search template处理复杂的查询

我们构建以下search template,其功能如下

可以通过name字段进行match,如果命中字段中的各个关键字相邻则有更高的权重打分,同时可以通过address字段进行模糊匹配,这三个查询只要命中一个即可;

man字段值必须符合输入的值;

POST _scripts/search_template_test.multi_search_template
{
    "script":{
        "lang":"mustache",
        "source":{
            "query":{
                "bool":{
                    "should":[
                        {
                            "match":{
                                "name":"{{name}}"
                            }
                        },
                        {
                            "match_phrase_prefix":{
                                "name":"{{name}}"
                            }
                        },
                        {
                            "query_string":{
                                "default_field":"address",
                                "query":"{{#join delimiter=' '}}address{{/join delimiter=' '}}"
                            }
                        }
                    ],
                    "filter":{
                        "term":{
                            "man":"{{man}}"
                        }
                    },
                    "minimum_should_match":1
                }
            }
        }
    }
}

通过以下参数命中前两条数据

POST search_template_test/_search/template
{
    "id":"search_template_test.multi_search_template",
    "params":{
        "name":"zhang sa",
        "address":[
            "*bei*",
            "*chi*"
        ],
        "man":true
    }
}


{
    "took":10,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":2,
        "max_score":1.8630463,
        "hits":[
            {
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"1",
                "_score":1.8630463,
                "_source":{
                    "name":"zhang san",
                    "age":30,
                    "man":true,
                    "address":"Hebei LangFang"
                }
            },
            {
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"2",
                "_score":1,
                "_source":{
                    "name":"li si",
                    "age":20,
                    "man":true,
                    "address":"BeiJing HaiDian"
                }
            }
        ]
    }
}

我们将man字段设置为false,从而只匹配第三条记录;

POST search_template_test/_search/template
{
    "id":"search_template_test.multi_search_template",
    "params":{
        "name":"zhang sa",
        "address":[
            "*bei*",
            "*chi*"
        ],
        "man":false
    }
}

{
    "took":4,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":1,
        "max_score":1,
        "hits":[
            {
                "_index":"search_template_test",
                "_type":"_doc",
                "_id":"3",
                "_score":1,
                "_source":{
                    "name":"liu hui",
                    "age":40,
                    "man":false,
                    "address":"NeiMengGu ChiFeng"
                }
            }
        ]
    }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK