搜索场景
有些时候,对于一些搜索刚入门的同学来说,提升 ElasticSearch 的搜索性能以及如何应对各种场景下的复杂搜索来采用最合适的 DSL,,无疑是非常苦难的。而且对于公司来说,最重要的是如何能够快速的产生业务价值,所以一般差不多点的公司都会有专门的 搜索优化团队来出模板,业务同学只要调用特定的客户端便可以。
ElasticSearch 为了提升专业性,专门提供了一种查询API,也就是接下来要介绍的 searchTemplate。
SearchTemplate
SearchTemplate 是一个查询模板,是ElasticSearch 提供的模板语言。其实走得是 script 脚本,lang 语言使用的是 mustache。
语法:POST _scripts/模板名称 + 请求体(“关键词 mustache”)
- lang 指定脚本语言
- source 指定要配置的搜索语句
- {{}} 指定你要替换的值
POST _scripts/movies-search
{
"script": {
"lang": "mustache",
"source": {
"_source": [
"title",
"genre",
"year"
],
"size": 20,
"query": {
"bool": {
"must": [
{
"match": {
"title": "{{must_value}}"
}
}
],
"filter": {
"range": {
"year": {
"lte": "{{lte}}",
"gte": "{{gte}}"
}
}
}
}
}
}
}
}
如上的语法就是创建了一个简单的搜索模板,是个 bool 查询,对 movies 的 title 进行全文分词搜索,对 year 进行过滤并且不加入算分。
模板方法的使用也很简单,只需要用关键词 params 指定搜索条件就可以。
POST movies/_search/template
{
"id":"movies-search", # 指定模板名
"params": {
"lte": 2005,
"gte": 1995,
"must_value": "love"
}
}
可以发现,结果已经被正确搜索了出来,这样一来对于业务方来说就隐藏了其细节,只需要关注传入的参数就可以。
使用语法
验证模板 validate search Template
ElasticSearch 提供了一个API来验证当前模板是否语法正确,可以不需要存储模板便可以直接看到效果。
语法:GET 索引名/_search/模板名称 + 请求体(“关键词 source”)
GET /movies/_search/template
{
"source": {
"query": {
"match": {
"title": "{{q}}"
}
}
},
"params": {
"q":"Love"
}
}
converting param to json 将参数作为json对象替换
Search Templae 提供了一种语法,将整个参数作为一个查询 json 传入替换,这种场景是为了解决有时候客户端同学需要自定义一些查询条件的时候使用。
语法:GET 索引名/_search/模板名称 + 请求体(“关键词 source”)
GET /movies/_search/template
{
"source": "{ \"query\": { \"match\": {{#toJson}}replace{{/toJson}} }}",
"params": {
"replace":{
"genre": "comedy"
}
},
"profile": true
}
如上的语法,其实最终是将 replace 这个参数的 { “genre”: "comedy“ } 作为一个整体来将{{#toJson}}replace{{/toJson}} }} 这一段完全替换掉。
转义过来的语法就是:
POST movies/_search
{
"query": {
"match": {
"genre": "comedy"
}
}
}
拼接数组为字符串 concatenation array
Search Templae 提供了一种语法,可以将你传入的数组按照一定的拼接语法成为一个字符串来做整体的查询。
语法:GET 索引名/_search/模板名称 + 请求体(“关键词{{#join delimiter=’ and ‘}}xxx{{/join delimiter=’ and '}}”)
- delimiter 为拼接的字符串
GET /movies/_search/template
{
"source": {
"query": {
"match": {
"title": "{{#join delimiter=' and '}}title{{/join delimiter=' and '}}"
}
}
},
"params": {
"title": ["love","tale"]
},
"profile": true
}
如上的语法,其实就是将title这个传入的数组,按照拼接 and 的方式,凭借成一个字符串去查询,然后替换掉title。
转义过来的语法就是:
POST movies/_search
{
"query": {
"match": {
"title": "love and tale"
}
}
}
默认值 default value
Search Template 还支持一种当客户端同学没有传入值得时候设置一个默认值的语法。
语法:GET 索引名/_search/模板名称 + 请求体(“关键词{{^end}}20{{/end}}”)
- end 为你要传入的那个参数
GET /movies/_search/template
{
"source": {
"query": {
"bool": {
"must": [
{"match": {
"title": "{{master}}"
}}
],
"filter": {
"range": {
"year": {
"lte": "{{lte}}{{^lte}}2005{{/lte}}",
"gte": "{{gte}}{{^gte}}1995{{/gte}}"
}
}
}
}
}
},
"params": {
"master": "love"
},
"profile": true
}
如上的语法,其实就是一个bool查询,根据你传入的master值来替换match匹配,但是过滤的时候,如果你没有传 lte 与 gte,那么这两个地方就会被替换成你设置的默认值。
转义过来的语法就是:
POST movies/_search
{
"query": {
"bool": {
"must": [
{"match": {
"title": "love"
}}
],
"filter": {
"range": {
"year": {
"lte": 2005,
"gte": 1995
}
}
}
}
}
}
查看模板
GET _scripts/movies-search
删除模板
DELETE _scripts/movies-search