一步步拆解解决 Elasticsearch 检索模板问题

robinent
发布于 2022-4-26 12:07
浏览
0收藏

1、线上实战提问


Elasticsearch做模版查询的时候,在使用 terms 进行批量查询的时候放入数组在模版中进行查询失败,类似于模版传入数组该如何实现?

 

问题来源:死磕Elasticsearch知识星球

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

查询语句:

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

查询模版参数:

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

以上内容看着很长,根据注释拆解为:

 

 •  定义索引、
 •  插入数据、
 •  创建模板、
 •  构造参数检索


四个子部分你就不会恐慌了。

 

2、知识点解读——搜索模板


一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区
很多人都听说使用过 索引模板 index template,索引模板的好处:

 

 •  便于跨索引统一建模;
 •  尤其适合数据量巨大、索引字段类似的业务系统;
 •  灵活便捷。


检索模板(search template)大家使用相对较少,在实战业务场景中:每次业务请求都要构造 DSL,比如:这次查title、下次查content,除此之外的 DSL 部分 都一样,但两次请求:后端代码那里就要有相应的修改和适配。有没有不修改、拼接DSL使用检索的方案?这就引出了搜索模板。

 

搜索模板与关系数据库中的存储过程非常相似。可以将常用查询定义为模板,并且使用 Elasticsearch 的应用程序可以简单地通过其 ID 引用查询。

 

模板接受在运行时指定参数。搜索模板存储在服务器端,可以在不更改客户端代码的情况下进行修改。

 

模板使用Mustache模板引擎表示。关于 Mustache 可以访问:

h

ttp://mustache.github.io/mustache.5.html。

 

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区


根据第一部分实战中的数据,定义了如下的模板。

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

该模板:支持用户自定义动态设置搜索字段及搜索参数字段。

 

实战中可以通过如下_scripts 的方式,将检索模板定义到服务器端。

 

如果想检索别的字段:客户端或者请求端传递不同的参数即可。

 

真正意义上的实现了:检索和请求参数的分离

 

更多原理和基础参见官方文档:

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-template.html

 

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区
以下内容摘自:Wood 大叔的——Elastic认证考试心得。

 

按照要求写一个search template


熟悉search template的mustache模版语言即可轻松写出,但是很遗憾,平常没用过search template,虽然知道个大概,但是当时写的时候,不知道哪里语法有问题,PUT template总是不成功。猜想可能是哪个位置的字符没有转译产生非法json字符,或者哪一层嵌套有问题。总之就是调试不成功,又浪费了很多时间。

 

https://elasticsearch.cn/article/6133

 

如上引用想说明的是:search template的语法比较复杂,如果没用过,很容易头大


3、问题拆解

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区
实战一把,报错如下:

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区


拆解一下。

 

 •  script 部分无非包括:检索部分和聚合部分。
 •  检索部分是定义 search template 的核心,聚合部分无需关注。


这个时候,可以写一个检索 DSL验证一下是否ok,如下:

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

 •  而检索和聚合都没错,那多半就是定义 search template 部分出错了。

 

问题就这么一点点拆解了。

 

上来直接改这个 DSL貌似也无从下手,那咱们就做:最小化处理吧。

 

抛去所有:_source、size、aggs、range query 部分,只保留 terms 脚本应该怎么正确的写?

 

来吧,实战一把:

 

 •  第一步:最小化 terms 检索模板。
一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

用现在正确的对比第一部分出错的,可以找到如下两处错误:

 

 •  错误1:source 里面的内容要加:"\" 。
 •  错误2:查询模版参数中的 statuses 和 itemid 位置写错了。


官方文档的说法: 

 

The {{#toJson}}parameter{{/toJson}} function can be used to convert parameters like maps and array to their JSON representation:

statuses 就是个辅助参数,我们核心的参数是 itemid。

 

 •  第二步:将第一步内容转成script 形式。
一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

 •  第三步:按照实战要求补全参数即可。


注意补全的时候,我建议:拷贝 DSL(格式化一行的版本)到第三方文本工具如:Nodepad++,全局替换。

一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

切记不要手敲,很容易出错。

 

替换到模板的 source 部分,然后再根据第一步、第二步内容修改即可。

 

 •  实战问题答案
一步步拆解解决 Elasticsearch 检索模板问题-鸿蒙开发者社区

拷贝 source 部分转换为脚本格式就可以,篇幅问题,不再赘述。

 

4、小结


看似复杂,拆解后便不复杂。

 

看似很难,拆解后就很简单。

 

检索模板用的好,前后端扯皮少、效率高很多!

 

你的小问题,我的大问题。

 

和你一起,死磕 Elasticsearch!

分类
收藏
回复
举报
回复
    相关推荐