参考文档【我的elasticsearch版本是5.4.3】:
https://www.elastic.co/guide/en/elasticsearch/reference/5.4/search-template.html
elasticsearch提供了查询模板,在需要较复杂的查询语句时比较方便。_search/template语句可以执行模板查询。模板文件使用mastache语言来预先构造出含参数的查询语句,等执行时传入参数即可得到结果。
模板语法
mustache语法参考http://mustache.github.io/mustache.5.html
我的使用:
环境和数据
拿到产品的运行日志(目前以ezdb产品为例),使用logstash将日志文件(.log文件)其导入elasticsearch中。
索引名称:
模式:logstash-[产品名称]-[日期],比如logstash-ezdb-2018.01.05,logstash-ezdb-2018.01.02
type:log(elasticsearch不建议在一个索引中使用多个type,并且在最新的6版本中会丢弃type)
几个重要字段及其类型(各字段含义可不深究,主要为了说明查询模板的构造方式):
字段 | 类型 |
@timeStamp | Date |
logtime | keyword |
uuid | keyword |
loglevel | keyword |
message | text |
|
|
问题
我现在要做这样一个页面:
实现
- 那我需要首先写出查询的模板:
{
"_source": ["logtime",”uuid”,”message”],
"query":{
"bool":{
"must":[{
"match":{
"{{filed}}":{
"query": "{{query_string}}",
"operator": "{{operator}}"
}
}
{{}}双大括号里面的是参数,使用时通过给参数赋值,mustache会用具体的参数值来填充在{{}}的位置,怎样使用呢?两种方式:
- 使用post推送到es中:
POST _search/template是接口,t1是自定义的模板名称,提交之后就可以使用模板t1来进行搜索了。
- 使用模板进行搜索
这就是一次简单使用了。
进阶问题:
问题一
查询结果的字段,即_source中包含哪些字段,我希望是可以参数化的,这样当查询结果的字段需要改变时就不需要改变模板了。
这个功能我在文档中并没有看到合适的,经过试验,下面的写法可行:
当参数source是数组时,{{#source}} {{/source}} 是循环,{{.}}代表数组内元素。传参方式:
问题二:
还有个问题,loglevel,如果我不想选这个呢,我想要所有级别的,那么就可以使用条件语句,如果不传入loglevel参数,那么查询语句就没有loglevel的条件:
按照文档中的内容,需要加上{{#loglevel}} {{loglevel}}条件,即如果有传入loglevel参数的赋值,那么就加上{{#loglevel}} {{loglevel}}中间的语句,而在使用时发现,这样在kibana中会提交不通过:
,OK,换种方式,使用file的形式,将这个模板存储在elasticsearch集群的安装目录config/scripts目录下,文件扩展名为.mustache:
这样就可以了,在查询的时候,需要指定模板的方式是file,如下:
不指定loglevel:
注意的是,在使用.mustache文件时,内容中是不含”template”关键字的,而在POST _search/template时,是含有”template”的,而且这个关键字是不能省略的,如果省略了,如果模板中只有一条语句,那么没有问题,但是如果有多条语句时,会只有第一个语句生效,后面的语句都没有生效,但是不报错,即,搜索不报错,但是搜索结果不对。