ES Search Template(下)

简介: ES Search Template

默认值

使用 {{var}}{{^var}}default{{/var}} 的方式设置默认值。

示例:

{
  "source": {
    "query": {
      "range": {
        "line_no": {
          "gte": "{{start}}",
          "lte": "{{end}}{{^end}}20{{/end}}"
        }
      }
    }
  },
  "params": { ... }
}

{{end}}{{^end}}20{{/end}} 就是给 end 设置了默认值为 20 。

params{ "start": 10, "end": 15 } 时,渲染结果是:

{
  "range": {
    "line_no": {
      "gte": "10",
      "lte": "15"
    }
  }
}

params{ "start": 10 } 时,end 就会使用默认值,渲染结果就是:

{
  "range": {
    "line_no": {
      "gte": "10",
      "lte": "20"
    }
  }
}

条件子句

有时候我们的参数是可选的,这时候就可以使用 {{#key}}  {{/key}}的语法。

示例,假设参数 line_no, start, end 都是可选的,使用 {{#key}}  {{/key}} 形如:

{
  "query": {
    "bool": {
      "must": {
        "match": {
          "line": "{{text}}"
        }
      },
      "filter": {
        {{#line_no}}
          "range": {
            "line_no": {
              {{#start}}
                "gte": "{{start}}"
                {{#end}},{{/end}}
              {{/start}}
              {{#end}}
                "lte": "{{end}}"
              {{/end}}
            }
          }
        {{/line_no}}
      }
    }
  }
}

1、 当参数为:

{
  "params": {
    "text": "words to search for",
    "line_no": {
      "start": 10,
      "end": 20
    }
  }
}

渲染结果是:

{
  "query": {
    "bool": {
      "must": {
        "match": {
          "line": "words to search for"
        }
      },
      "filter": {
        "range": {
          "line_no": {
            "gte": "10",
            "lte": "20"
          }
        }
      }
    }
  }
}






2、 当参数为:

{
  "params": {
    "text": "words to search for"
  }
}

渲染结果为:

{
  "query": {
    "bool": {
      "must": {
        "match": {
          "line": "words to search for"
        }
      },
      "filter": {}
    }
  }
}

3、当参数为:

{
  "params": {
    "text": "words to search for",
    "line_no": {
      "start": 10
    }
  }
}

渲染结果为:

{
  "query": {
    "bool": {
      "must": {
        "match": {
          "line": "words to search for"
        }
      },
      "filter": {
        "range": {
          "line_no": {
            "gte": 10
          }
        }
      }
    }
  }
}

4、当参数为:

{
  "params": {
    "text": "words to search for",
    "line_no": {
      "end": 20
    }
  }
}

渲染结果为:

{
  "query": {
    "bool": {
      "must": {
        "match": {
          "line": "words to search for"
        }
      },
      "filter": {
        "range": {
          "line_no": {
            "lte": 20
          }
        }
      }
    }
  }
}

需要注意的是在 JSON 对象中,

{
  "filter": {
    {{#line_no}}
    ...
    {{/line_no}}
  }
}

这样直接写 {{#line_no}} 肯定是非法的JSON格式,你必须转换为 JSON 字符串。

URLs 编码

使用 {{#url}}value{{/url}} 的方式可以进行 HTML 编码转义。

示例:

GET _render/template
{
  "source": {
    "query": {
      "term": {
        "http_access_log": "{{#url}}{{host}}/{{page}}{{/url}}"
      }
    }
  },
  "params": {
    "host": "https://www.elastic.co/",
    "page": "learn"
  }
}

渲染结果:

{
  "template_output": {
    "query": {
      "term": {
        "http_access_log": "https%3A%2F%2Fwww.elastic.co%2F%2Flearn"
      }
    }
  }
}

Mustache 基本语法

上文中的 {{ }} 语法其实就是 mustache language ,补充介绍下基本的语法规则。

使用 {{key}}

模板:Hello {{name}}

输入:

{
    "name": "Chris"
}

输出:Hello Chris

使用 {{{key}}} 避免转义

所有变量都会默认进行 HTML 转义。

模板:{{company}}

输入:

{
    "company": "<b>GitHub</b>"
}

输出:<b>GitHub</b>

使用 {{{ }}} 避免转义。

模板:{{{company}}}

输入:

{
    "company": "<b>GitHub</b>"
}

输出:GitHub

使用 {{#key}}  {{/key}} 构造区块

1、 当 key 是 false 或者空列表将会忽略 模板:

Shown.
    {{#person}}
        Never shown!
    {{/person}}

输入:

{
    "person": false
}

输出:

   Shown.

2、 当 key 非空值则渲染填充 模板:

   {{#repo}}
        <b>{{name}}</b>
    {{/repo}}

输入:

{
    "repo": [
        { "name": "resque" },
        { "name": "hub" },
        { "name": "rip" }
    ]
}

输出:

    <b>resque</b>
    <b>hub</b>
    <b>rip</b>

3、当 key 是函数则调用后渲染 模板:

   {{#wrapped}}
        {{name}} is awesome.
    {{/wrapped}}

输入:

{
    "name": "Willy",
    "wrapped": function() {
        return function(text, render) {
            return "<b>" + render(text) + "</b>"
        }
    }
}

输出:

    <b>Willy is awesome.</b>

4、当 key 是非 false 且非列表 模板:

    {{#person?}}
        Hi {{name}}!
    {{/person?}}

输入:

{
    "person?": { "name": "Jon" }
}

输出:

    Hi Jon!

使用 {{^key}}  {{/key}} 构造反区块

{{^key}}  {{/key}} 的语法与 {{#key}}  {{/key}} 类似,不同的是,当 key 不存在,或者是 false ,又或者是空列表时才渲染输出区块内容。

模板:

    {{#repo}}
        <b>{{name}}</b>
    {{/repo}}
    {{^repo}}
        No repos :(
    {{/repo}}

输入:

{
    "repo": []
}

输出:

    No repos :(

使用 {{! }} 添加注释

{{! }} 注释内容将会被忽略。

模板:

<h1>Today{{! ignore me }}.</h1>

输出:

<h1>Today.</h1>

使用 {{> }} 子模块

模板:

base.mustache:
<h2>Names</h2>
{{#names}}
    {{> user}}
{{/names}}
user.mustache:
<strong>{{name}}</strong>

其实也就等价于:

<h2>Names</h2>
{{#names}}
    <strong>{{name}}</strong>
{{/names}}

使用 {{=  =}} 自定义定界符

有时候我们需要改变默认的定界符 {{ }} ,那么就可以使用 {{=  =}} 的方式自定义定界符。

例如:

{{=<% %>=}}

定界符被定义为了 <% %>,这样原先 {{key}} 的使用方式就变成了 <%key%>。再使用:

<%={{ }}=%>

就重新把定界符改回了 {{ }}

更多语法详情请查阅官方文档 mustache language 。

结语

使用 search template 可以对搜索进行有效的解耦,即应用程序只需要关注搜索参数与返回结果,而不用关注具体使用的 DSL 查询语句,到底使用哪种 DSL 则由搜索模板进行单独管理。

目录
相关文章
|
5月前
webpack 使用打包报错 ERROR in node_modules\@types\node\ts4.8\assert.d.ts
webpack 使用打包报错 ERROR in node_modules\@types\node\ts4.8\assert.d.ts
124 0
|
7月前
|
JavaScript
Angular 应用里 server.ts 文件的 APP_BASE_HREF token 的用法?
Angular 应用里 server.ts 文件的 APP_BASE_HREF token 的用法?
52 0
|
1月前
报错/ ./node_modules/axios/lib/platform/index.js Module parse failed: Unexpected token (5:2)怎么解决?
报错/ ./node_modules/axios/lib/platform/index.js Module parse failed: Unexpected token (5:2)怎么解决?
|
2月前
Angular启动/node_modules/@types/node/index.d.ts (20,1): Invalid ‘reference‘ directive syntax.
Angular启动/node_modules/@types/node/index.d.ts (20,1): Invalid ‘reference‘ directive syntax.
21 2
|
6月前
|
资源调度
Cannot find module ‘\node_modules\ejs\postinstall.js
Cannot find module ‘\node_modules\ejs\postinstall.js
40 0
|
8月前
|
JSON API 数据格式
ES Search Template(上)
ES Search Template
30 0
|
5月前
|
JavaScript
【Vue Error】 error Component name “product“ should always be multi-word vue/multi-word-compone……
【Vue Error】 error Component name “product“ should always be multi-word vue/multi-word-compone……
|
6月前
|
JavaScript
Node.js Error: Cannot find module express
Node.js Error: Cannot find module express
|
7月前
|
JavaScript
Vue中遇到的Bug( Component name “School“ should always be multi-word vue/multi-word-component-names)
Vue中遇到的Bug( Component name “School“ should always be multi-word vue/multi-word-component-names)
51 0
|
9月前
|
JavaScript 前端开发
成功解决Component template should contain exactly one root element
成功解决Component template should contain exactly one root element