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

Elasticsearch 搜索模板(Search Templates)把“可配置查询”装进 Mustache

1. 什么是 Search Template?能解决什么问题?

搜索模板是存储在 ES 集群里的 Mustache 模板(lang: mustache)。你把一份标准 _search 请求体写成模板,变量交给 params,每次调用只需传参即可:

  • 搜索前端:把输入框内容作为 params 传进来,屏蔽 DSL 细节与危险语法。
  • 业务后端:把“检索策略”与“业务代码”解耦——需要改查询逻辑时,只改模板,不用发版。
  • 多团队协作:数据/搜索工程师直接维护模板,应用侧只负责传参和渲染结果。

模板以脚本的形式存在集群状态中(Stored Script),受脚本开关与限制影响(如禁用脚本、限制大小等)。

2. 快速上手(5 分钟)

2.1 创建/更新模板

PUT _scripts/my-search-template
{"script": {"lang": "mustache","source": {"query": { "match": { "message": "{{query_string}}" } },"from": "{{from}}","size": "{{size}}"}}
}

2.2 本地渲染与调试(不真正搜索)

POST _render/template
{"id": "my-search-template","params": { "query_string": "hello world", "from": 20, "size": 10 }
}

2.3 运行模板化搜索

GET my-index/_search/template
{"id": "my-search-template","params": { "query_string": "hello world", "from": 0, "size": 10 }
}

2.4 批量运行(多查询一起发)

GET my-index/_msearch/template
{ }
{ "id": "my-search-template", "params": { "query_string": "hello world", "from": 0, "size": 10 } }
{ }
{ "id": "my-other-search-template", "params": { "query_type": "match_all" } }

2.5 管理模板

  • 获取某个模板:GET _scripts/my-search-template
  • 列出全部:GET _cluster/state/metadata?filter_path=metadata.stored_scripts
  • 删除:DELETE _scripts/my-search-template

3. Mustache 语法要点(结合搜索的“刚需功能”)

Mustache 是逻辑少的模板语言,靠变量替换 + 区块控制完成拼装。

3.1 变量与默认值

POST _render/template
{"source": {"query": { "match": { "message": "{{query_string}}" } },"from": "{{from}}{{^from}}0{{/from}}","size": "{{size}}{{^size}}10{{/size}}"},"params": { "query_string": "hello world" }
}
  • {{var}}:变量
  • {{^var}}default{{/var}}:当 var 不存在/为空时用默认值

3.2 条件与 if-else

"filter": [{{#year_scope}}{ "range": { "@timestamp": { "gte": "now-1y/d", "lt": "now/d" } }},{{/year_scope}}{ "term": { "user.id": "{{user_id}}" } }
]
  • {{#cond}}...{{/cond}}:cond 为真则渲染
  • {{^cond}}...{{/cond}}:cond 为假则渲染
  • 两者可组合做 if-else

3.3 工具函数(Lambda)

  • URL 编码{{#url}}{{host}}/{{page}}{{/url}}
  • 拼接数组{{#join delimiter='||'}}date.formats{{/join}}
  • 转 JSON{{#toJson}}tags{{/toJson}}(数组/对象都能转)

⚠️ 强烈建议:凡是数组、对象、子查询块,一律用 toJson 输出,避免引号/逗号导致的无效 JSON

3.4 列表循环与“尾逗号”陷阱

"fields": [{{#text_fields}}{{user_name}}{{^last}},{{/last}}{{/text_fields}}]
  • 用一个布尔字段 last 控制是否加逗号,避免 [a,b,] 这种无效 JSON。

3.5 更换变量分隔符(小众)

{{=( )=}}
"message": "(query_string)"
(={{ }}=)

在模板内部临时把 {{ }} 改为 (),适用于与其他模板语言冲突的场景。

不支持:Mustache 的 partials 特性在 ES 搜索模板里不可用。

4. 进阶:把“复杂检索策略”模板化

Search Template 的 source 支持 _search 的全部请求体,你可以模板化任何结构:Query DSL、Retrievers、kNN、RRF、LTR 重排、Async Search 参数等。

4.1 混合检索(RRF)模板

PUT _scripts/rrf-template
{"script": {"lang": "mustache","source": {"retriever": {"rrf": {"rank_window_size": "{{rank_window}}{{^rank_window}}100{{/rank_window}}","retrievers": [{ "standard": { "query": { "match": { "text": "{{q}}" } } } },{ "standard": { "query": { "sparse_vector": {"field": "vector.tokens", "inference_id": "{{elser_id}}", "query": "{{q}}"}}}}]}},"size": "{{size}}{{^size}}10{{/size}}"}}
}

使用:

GET my-index/_search/template
{"id": "rrf-template","params": { "q": "blue shoes sale", "elser_id": "my-elser-endpoint", "size": 20 }
}

4.2 LTR(学习排序)重排模板

PUT _scripts/ltr-rescore
{"script": {"lang": "mustache","source": {"retriever": {"rescorer": {"retriever": { "standard": { "query": { "multi_match": {"query": "{{q}}", "fields": ["title^2","content"]}}}},"window_size": "{{win}}{{^win}}100{{/win}}","learning_to_rank": {"model_id": "{{model_id}}","params": { "query_text": "{{q}}" }}}},"from": "{{from}}{{^from}}0{{/from}}","size": "{{size}}{{^size}}10{{/size}}"}}
}

生产要点:window_size from + size,否则可能出现未重排的文档排在前面。

4.3 可选项与权限控制

  • 把“是否限定时间范围”“是否加高权重字段”等开关做成布尔参数,套 {{#cond}}...{{/cond}}
  • 把“敏感过滤”写入模板,前端只能传白名单参数,降低注入风险

5. 工程化落地清单

  1. 命名与版本
  • 模板 id 采用 search.<domain>.<scenario>.v1,修改不兼容时递增版本,便于回滚。
  1. 参数白名单
  • 应用层只接受你定义好的 params 字段;对字符串做长度限制、对数组做最大项数限制
  1. 渲染前自检
  • _render/template;若 JSON 解析失败立即中断,返回明确错误给上游。
  1. 监控与审计
  • 记录模板 id、参数快照(脱敏)、渲染耗时、命中率、took、超时率,为回归与 A/B 提供数据。
  1. 性能开关
  • 大范围查询配 timeout;只要命中数就 size:0 + terminate_after;
  • 不追求精确总数就别 track_total_hits:true(或给个阈值),保性能可控。
  1. 安全与脚本限制
  • 了解脚本相关设置(如禁用脚本会影响模板);控制模板大小与数量,避免集群状态膨胀。

6. 常见坑与排雷

  • 尾逗号/引号错位:数组/对象拼装一律用 toJson;列表循环用 last 变量收尾。
  • 空变量导致非法查询:对可空字段加默认值或用条件包裹。
  • 把用户输入直塞进 DSL:一定做白名单与长度校验(模板只是替换,不会自动防注入)。
  • 脚本被禁用:排查集群脚本设置(模板属于 stored script)。
  • 多团队改动互相影响:对模板加 代码评审/发布流程,并约定 id 与版本策略。

7. 一键迁移套路(给你一套模版骨架)

PUT _scripts/search.web.v1
{"script": {"lang": "mustache","source": {"query": {"bool": {"filter": [{{#time_range}}{ "range": { "@timestamp": { "gte": "{{gte}}", "lte": "{{lte}}" } } },{{/time_range}}{{#env}}{ "term": { "service.env": "{{env}}" } },{{/env}}{{#category}}{ "term": { "category.keyword": "{{category}}" } }{{/category}}],"must": [{{#q}}{ "simple_query_string": { "query": "{{q}}", "fields": ["title^2","content"] } }{{/q}}]}},"_source": ["@timestamp","title","url","snippet"],"from": "{{from}}{{^from}}0{{/from}}","size": "{{size}}{{^size}}10{{/size}}","timeout": "{{timeout}}{{^timeout}}2s{{/timeout}}"}}
}

8. 小结

  • Search Template = “可配置的搜索策略”:把 DSL/检索管线参数化,统一在 ES 侧托管。
  • Mustache 提供拼装能力:默认值、条件、列表、URL 编码、toJson 一应俱全。
  • 与新特性无缝结合:Retrievers / RRF / LTR / 语义重排 都能以模板方式下发。
  • 工程实践很关键:参数白名单、渲染自检、监控审计、版本与回滚,要一步到位。

如果你贴上真实索引 mapping期望的检索策略(词法/语义/融合/重排),我可以帮你把它们整理成一套模板库(含渲染/校验脚本与 Kibana 演示面板),直接接入生产。

http://www.lryc.cn/news/616108.html

相关文章:

  • 【AI学习从零至壹】AI调用MCP抓包分析pcap原始报文
  • Spring Boot 开发三板斧:POM 依赖、注解与配置管理
  • 我如何从安全运维逆袭成企业CSO
  • 专题二_滑动窗口_串联所有单词的子串
  • SQL约束:数据完整性的守护者
  • 编程基础之多维数组——同行列对角线的格
  • 2.变量和常量
  • 【秋招笔试】2025.08.09美团秋招算法岗机考真题-第二题
  • 深度解析1688关键字搜索API接口:技术实现与应用探索
  • 电脑本地摄像头做成rtsp流调用测试windows系统中
  • 托福阅读记录
  • Shell脚本-四则运算符号
  • spring-boot-starter-data-redis 与 org.redisson 区别 联系
  • Shell脚本-数组定义
  • 数据结构:栈和队列(Stack Queue)基本概念与应用
  • 从0开始的中后台管理系统-5(userList页面功能实现)
  • JS数组排序算法
  • 第三章 向量
  • ECharts Y轴5等分终极解决方案 - 动态适配缩放场景
  • 计算机网络:(十四)传输层(下)详细讲解TCP报文段的首部格式,TCP 可靠传输的实现与TCP 的流量控制
  • 一些js数组去重的实现算法
  • Android的事件分发流程、Kotlin协程、4大组件、Handler机制、架构设计、性能优化、内存泄漏
  • 系统架构设计师备考之架构设计高级知识
  • Flink提交流程全解析:从模式到实践
  • DevOps:从GitLab .gitlab-ci.yml 配置文件到CI/CD
  • [论文阅读] 人工智能 + 软件工程 | 大型语言模型对决传统方法:多语言漏洞修复能力大比拼
  • FlinkSQL Joins全解析
  • 从MySQL到大数据平台:基于Spark的离线分析实战指南
  • Spark学习(Pyspark)
  • 在VMware中安装统信UOS桌面专业版