当前位置: 首页 > news >正文

Elasticsearch Search Template 搜索模板

Elasticsearch Search Template

所谓 search template 搜索模板其实就是:

  1. 预先定义好查询语句 DSL 的结构并预留参数
  2. 搜索的时再传入参数值
  3. 渲染出完整的 DSL ,最后进行搜索

使用搜索模板可以将 DSL 从应用程序中解耦出来,并且可以更加灵活的更改查询语句。

例如:

GET _search/template
{"source" : {"query": {"match" : {"{{my_field}}" : "{{my_value}}"}}},"params" : {"my_field" : "message","my_value" : "foo"}
}

构造出来的 DSL 就是:

{"query": {"match": {"message": "foo"}}
}

在模板中通过 {{ }} 的方式预留参数,然后查询时再指定对应的参数值,最后填充成具体的查询语句进行搜索。


搜索模板 API

为了实现搜索模板和查询分离,我们首先需要单独保存和管理搜索模板。

保存搜索模板

使用 scripts API 保存搜索模板(不存在则创建,存在则覆盖)。示例:

POST _scripts/<templateid>
{"script": {"lang": "mustache","source": {"query": {"match": {"title": "{{query_string}}"}}}}
}
查询搜索模板
GET _scripts/<templateid>
删除搜索模板
DELETE _scripts/<templateid>
使用搜索模板

示例:

GET _search/template
{"id": "<templateid>","params": {"query_string": "search words"}
}

params 中的参数与搜索模板中定义的一致,上文保存搜索模板的示例是 {{query_string}},所以这里进行搜索时对应的参数就是 query_string

检验搜索模板

有时候我们想看看搜索模板输入了参数之后渲染成的 DSL 到底长啥样。

示例:

GET _render/template
{"source": "{ \"query\": { \"terms\": {{#toJson}}statuses{{/toJson}} }}","params": {"statuses" : {"status": [ "pending", "published" ]}}
}

返回的结果就是:

{"template_output": {"query": {"terms": {"status": ["pending","published"]}}}
}

{{#toJson}} {{/toJson}} 就是转换成 json 格式。

已经保存的搜索模板可以通过以下方式查看渲染结果:

GET _render/template/<template_name>
{"params": {"..."}
}
使用 explainprofile 参数

示例:

GET _search/template
{"id": "my_template","params": {"status": [ "pending", "published" ]},"explain": true
}
GET _search/template
{"id": "my_template","params": {"status": [ "pending", "published" ]},"profile": true
}

模板渲染

填充简单值
GET _search/template
{"source": {"query": {"term": {"message": "{{query_string}}"}}},"params": {"query_string": "search words"}
}

渲染出来的 DSL 就是:

{"query": {"term": {"message": "search words"}}
}
将参数转换为 JSON

使用 {{#toJson}}parameter{{/toJson}} 会将参数转换为 JSON。

GET _search/template
{"source": "{ \"query\": { \"terms\": {{#toJson}}statuses{{/toJson}} }}","params": {"statuses" : {"status": [ "pending", "published" ]}}
}

渲染出来的 DSL 就是:

{"query": {"terms": {"status": ["pending","published"]}}
}

对象数组的渲染示例:

GET _search/template
{"source": "{\"query\":{\"bool\":{\"must\": {{#toJson}}clauses{{/toJson}} }}}","params": {"clauses": [{ "term": { "user" : "foo" } },{ "term": { "user" : "bar" } }]}
}

渲染结果就是:

{"query": {"bool": {"must": [{ "term": { "user" : "foo" } },{ "term": { "user" : "bar" } }]}}
}
将数组 join 成字符串

使用 {{#join}}array{{/join}} 可以将数组 join 成字符串。

示例:

GET _search/template
{"source": {"query": {"match": {"emails": "{{#join}}emails{{/join}}"}}},"params": {"emails": [ "aaa", "bbb" ]}
}

渲染结果:

{"query" : {"match" : {"emails" : "aaa,bbb"}}
}

除了默认以 , 分隔外,还可以自定义分隔符,示例:

{"source": {"query": {"range": {"born": {"gte": "{{date.min}}","lte": "{{date.max}}","format": "{{#join delimiter='||'}}date.formats{{/join delimiter='||'}}"}}}},"params": {"date": {"min": "2016","max": "31/12/2017","formats": [ "dd/MM/yyyy", "yyyy" ]}}
}

例子中的 {{#join delimiter='||'}} {{/join delimiter='||'}} 意思就是进行 join 操作,分隔符设置为 || ,渲染结果就是:

{"query": {"range": {"born": {"gte": "2016","lte": "31/12/2017","format": "dd/MM/yyyy||yyyy"}}}
}
默认值

使用 {{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>"
}

输出:&lt;b&gt;GitHub&lt;/b&gt;

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

模板:{{{company}}}

输入:

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

输出:<b>GitHub</b>

使用 {{#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 则由搜索模板进行单独管理。

相关文章:

Elasticsearch Search Template 搜索模板

Elasticsearch Search Template 所谓 search template 搜索模板其实就是&#xff1a; 预先定义好查询语句 DSL 的结构并预留参数搜索的时再传入参数值渲染出完整的 DSL &#xff0c;最后进行搜索 使用搜索模板可以将 DSL 从应用程序中解耦出来&#xff0c;并且可以更加灵活的…...

2024年10月-2025年5月 Oracle 19c OCM 考试安排

2024年10月-2025年5月 Oracle 19c OCM 考试安排&#xff1a; 北京考场&#xff1a; 上海考场&#xff1a; 更新时间&#xff1a;2024年10月25日 Oracle 19c OCM往期学员成绩展示&#xff1a; Oracle 19c OCM认证证书&#xff08;电子版&#xff09;...

VMware虚拟机安装KailLinux系统

目录 简介 系统镜像下载 配置虚拟机 安装系统镜像 切换中文界面 后置内容 修改root密码 ssh服务 对互联网的热爱&#xff0c;尝试安装另一套Linux系统。 简介 Kali Linux是一个专为网络安全和渗透测试设计的Linux发行版&#xff0c;它包含了大量安全相关的工具和软件…...

G2 基于生成对抗网络(GAN)人脸图像生成

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 基于生成对抗网络&#xff08;GAN&#xff09;人脸图像生成 这周将构建并训练一个生成对抗网络&#xff08;GAN&#xff09;来生成人脸图像。 GAN 原理概述 …...

R学习笔记-单因素重复测量方差分析

R语言之重复测量方差分析——ezANOVA的使用与解析 - 知乎 单因素重复测量方差分析(One-Way Repeated Measures ANOVA)——R软件实现 - 梦特医数通 ### 清空environment rm(list ls()) ### 加载包 if (!require("tidyverse")) install.packages("tidyverse&quo…...

HTML练习题:彼岸的花(web)

展示效果: 代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>彼岸の花</title><style…...

(蓝桥杯C/C++)——常用库函数

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、 二分查找 1.二分查找的前提 2.binary_ search函数 3.lower_bound和upper_bound 二、排序 1.sort概念 2.sort的用法 3.自定义比较函数 三、全排列 1.next p…...

GPT-Sovits-2-微调模型

1. 大致步骤 上一步整理完数据集后&#xff0c;此步输入数据, 微调2个模型VITS和GPT&#xff0c;位置在 <<1-GPT-SoVITS-tts>>下的<<1B-微调训练>> 页面的两个按钮分别执行两个文件: <./GPT_SoVITS/s2_train.py> 这一步微调VITS的预训练模型…...

【数据结构 | PTA】懂蛇语

懂蛇语 在《一年一度喜剧大赛》第二季中有一部作品叫《警察和我之蛇我其谁》&#xff0c;其中“毒蛇帮”内部用了一种加密语言&#xff0c;称为“蛇语”。蛇语的规则是&#xff0c;在说一句话 A 时&#xff0c;首先提取 A 的每个字的首字母&#xff0c;然后把整句话替换为另一…...

Python——自动化发送邮件

在数字化时代&#xff0c;电子邮件是商务沟通和个人联络的重要工具。自动化邮件发送可以节省时间&#xff0c;提高效率。Python&#xff0c;作为一种强大且灵活的编程语言&#xff0c;提供了多种库来支持邮件的自动化发送。本文将详细介绍如何使用Python的smtplib和email库来编…...

MTKLauncher_布局页面分析

文章目录 前言遇到的困难点针对性解决困难 需求相关资料Launcher3 源码 目录简单介绍Launcher3 简介及页面布局分析UI整体架构数据加载布局加载布局加载核心思想device_profiles.xml 加载InvariantDeviceProfileinitGrid(context, gridName)getPredefinedDeviceProfilesinvDist…...

C#实现隐藏和显示任务栏

实现步骤 为了能够控制Windows任务栏&#xff0c;我们需要利用Windows API提供的功能。具体来说&#xff0c;我们会使用到user32.dll中的两个函数&#xff1a;FindWindow和ShowWindow。这两个函数可以帮助我们找到任务栏窗口&#xff0c;并对其执行显示或隐藏的操作 引入命名空…...

基于springboot+vue实现的公司财务管理系统(源码+L文+ppt)4-102

基于springbootvue实现的公司财务管理系统&#xff08;源码L文ppt&#xff09;4-102 摘要 本系统是基于SpringBoot框架开发的公司财务管理系统,该系统包含固定资产管理、资产申领管理、资产采购管理、员工工资管理等功能。公司财务管理系统是一种帮助公司进行有效资金管理、会…...

rnn/lstm

tip&#xff1a;本人比较小白&#xff0c;看到july大佬的文章受益匪浅&#xff0c;现在其文章基础上加上自己的归纳、理解&#xff0c;以及gpt的答疑&#xff0c;如果有侵权会删。 july大佬文章来源&#xff1a;如何从RNN起步&#xff0c;一步一步通俗理解LSTM_rnn lstm-CSDN博…...

袋鼠云产品功能更新报告12期|让数据资产管理更高效

本期&#xff0c;我们更新和优化了数据资产平台相关功能&#xff0c;为您提供更高效的产品能力。以下为第12期袋鼠云产品功能更新报告&#xff0c;请继续阅读。 一、【元数据】重点更新 &#xff5c;01 元数据管理优化&#xff0c;支持配置表生命周期 之前系统中缺少一个可以…...

MATLAB——入门知识

内容源于b站清风数学建模 目录 1.帮助文档 2.注释 3.特殊字符 4.设置MATLAB数值显示格式 4.1.临时更改 4.2.永久改 5.常用函数 6.易错点 1.帮助文档 doc sum help sum edit sum 2.注释 ctrl R/T 3.特殊字符 4.设置MATLAB数值显示格式 4.1.临时更改 format lon…...

C#从零开始学习(用户界面)(unity Lab4)

这是书本中第四个unity Lab 在这次实验中,将学习如何搭建一个开始界面 分数系统 点击球,会增加分数 public void ClickOnBall(){Score;}在OneBallBehaviour类添加下列方法 void OnMouseDown(){GameController controller Camera.main.GetComponent<GameController>();…...

Axure PR 9 多级下拉清除选择器 设计交互

大家好&#xff0c;我是大明同学。 Axure选择器是一种在交互设计中常用的组件&#xff0c;这期内容&#xff0c;我们来探讨Axure中选择器设计与交互技巧。 OK&#xff0c;这期内容正式开始 下拉列表选择输入框元件 创建选择输入框所需的元件 1.在元件库中拖出一个矩形元件。…...

分布式项目pom配置

1. 父项目打包方式为 pom <packaging>pom</packaging> 2. 父项目版本配置 <properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncod…...

2. Flink快速上手

文章目录 1. 环境准备1.1 系统环境1.2 安装配置Java 8和Scala 2.121.3 使用集成开发环境IntelliJ IDEA1.4 安装插件2. 创建项目2.1 创建工程2.1.1 创建Maven项目2.1.2 设置项目基本信息2.1.3 生成项目基本框架2.2 添加项目依赖2.2.1 添加Flink相关依赖2.2.2 添加slf4j-nop依赖2…...

Latte文本到视频生成实战:打造个性化AI视频的终极指南

Latte文本到视频生成实战&#xff1a;打造个性化AI视频的终极指南 【免费下载链接】Latte [TMLR 2025] Latte: Latent Diffusion Transformer for Video Generation. 项目地址: https://gitcode.com/gh_mirrors/la/Latte Latte是一款基于TMLR 2025研究成果的文本到视频…...

TrollInstallerX终极指南:如何高效部署iOS越狱工具的专业解决方案

TrollInstallerX终极指南&#xff1a;如何高效部署iOS越狱工具的专业解决方案 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 在iOS 14.0到16.6.1系统上安装TrollStore一…...

3步搞定微信聊天记录导出:Mac用户必备的数据备份指南

3步搞定微信聊天记录导出&#xff1a;Mac用户必备的数据备份指南 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否担心珍贵的微信聊天记录因为手机丢失或系统升级而…...

JAVA:类和对象完全解析

一、编程世界的乐高积木在面向对象编程&#xff08;OOP&#xff09;的宇宙中&#xff0c;类&#xff08;Class&#xff09;和对象&#xff08;Object&#xff09;如同乐高积木的基础模块。如果把程序看作一个虚拟城市&#xff0c;类就是建筑设计图&#xff0c;而对象则是根据图…...

Windows系统美化终极指南:如何快速实现个性化定制与性能优化 [特殊字符]

Windows系统美化终极指南&#xff1a;如何快速实现个性化定制与性能优化 &#x1f680; 【免费下载链接】Atlas &#x1f680; An open and lightweight modification to Windows, designed to optimize performance, privacy and usability. 项目地址: https://gitcode.com/…...

Degrees of Lewdity中文本地化完全指南:解决游戏语言障碍的3个实用技巧

Degrees of Lewdity中文本地化完全指南&#xff1a;解决游戏语言障碍的3个实用技巧 你是否因Degrees of Lewdity英文界面而无法深入体验游戏&#xff1f;是否曾因汉化步骤繁琐而放弃尝试&#xff1f;本指南将通过模块化解决方案&#xff0c;帮助你快速完成游戏汉化&#xff0c…...

长期使用Taotoken Token Plan套餐在项目开发中的成本节省感受

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 长期使用Taotoken Token Plan套餐在项目开发中的成本节省感受 1. 项目背景与计费模式选择 我们团队负责一个中型规模的AI应用项目…...

用emWin定时器在STM32上做个简易秒表:从对话框UI到后台逻辑的完整实现

用emWin定时器在STM32上实现高精度秒表&#xff1a;从UI设计到多任务协同的工程实践 在嵌入式GUI开发中&#xff0c;精确的时间控制往往决定着用户体验的成败。当我们需要在STM32平台上实现一个毫秒级响应的秒表应用时&#xff0c;emWin的窗口管理器定时器(WM_TIMER)便成为连接…...

蓝牙窃密攻防实战:从协议漏洞到固件后门,国家安全部警示的近场威胁全解析

2026年5月11日&#xff0c;国家安全部官方发布重磅警示&#xff0c;明确指出蓝牙设备已成为不法分子实施近距离窃密、监听、跟踪的"隐形獠牙"。从日常使用的无线耳机、智能手表&#xff0c;到办公场景的蓝牙键鼠、会议音箱&#xff0c;再到工业控制中的蓝牙传感器&am…...

虚假信息注入下异构系统弹性纳什均衡【附代码】

✨ 长期致力于博弈论、分布式纳什均衡、虚假信息注入攻击、线性系统、参数不确定、事件触发研究工作&#xff0c;擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;虚假信息观…...