十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OpenSearch查询DSL完全指南:Bool、Term、Range、Wildcard等10大查询类型一篇讲透

OpenSearch查询DSL完全指南:Bool、Term、Range、Wildcard等10大查询类型一篇讲透 OpenSearch查询DSL完全指南Bool、Term、Range、Wildcard等10大查询类型一篇讲透【免费下载链接】OpenSearch Open source distributed and RESTful search engine.项目地址: https://gitcode.com/gh_mirrors/op/OpenSearchOpenSearch 是一款开源的分布式 RESTful 搜索引擎其查询 DSLDomain Specific Language是开发者的核心武器。本指南面向新手用一篇通俗易懂的文章讲透 OpenSearch 查询 DSL 中最常用的 10 大查询类型Bool、Term、Terms、Range、Wildcard、Match、Match Phrase、Match All、Exists 和 Ids帮助你快速写出正确且高效的搜索语句。为什么需要掌握 OpenSearch 查询 DSL在 OpenSearch 中几乎所有搜索请求都通过一个 JSON 格式的query参数发出。查询 DSL 的设计哲学是每个查询都是一个 JSON 对象并且可以自由嵌套组合。掌握 10 大查询类型就能覆盖日常 90% 以上的搜索场景 。这些查询的源码实现都位于 server/src/main/java/org/opensearch/index/query/ 目录下每个查询类型对应一个 Builder 类想深入原理的同学可以直接阅读源码。10 大查询类型速览表查询类型DSL 关键字适用场景是否影响相关性评分布尔组合bool组合多条件过滤取决于子句精确匹配term状态、分类、ID 等不分词字段是多值匹配terms字段等于多个值之一是范围查询range价格、时间、年龄区间是通配符wildcard模糊前缀/后缀匹配是全文匹配match搜索框关键词检索是短语匹配match_phrase精确短语/连续词序是匹配全部match_all无过滤条件、取全量否字段存在exists判断某字段是否非空否按 ID 取数ids批量获取指定文档否Bool 查询组合条件的万能胶水Bool 查询是 OpenSearch 查询 DSL 中最强大的组合器它允许你用 4 种子句把多个查询拼起来must必须匹配且参与相关性评分filter必须匹配但不参与评分性能更好推荐用于纯过滤should可选匹配命中可加分must_not必须不匹配一个电商搜索的典型例子——华为手机价格 1000 到 5000 元不含赠品标题含 5G 加分{ query: { bool: { must: [ { match: { title: 华为 手机 } } ], filter: [ { range: { price: { gte: 1000, lte: 5000 } } }, { term: { status: on_sale } } ], must_not: [ { term: { tags: 赠品 } } ], should: [ { match: { title: 5G } } ], minimum_should_match: 0 } } }几个实用技巧性能优先纯条件过滤如时间、状态、分类尽量放进filter结果会被缓存minimum_should_match当 bool 中只有should子句时默认至少命中 1 个该参数可控制命中数量嵌套bool内部还可以再嵌套bool表达复杂逻辑源码解析见 BoolQueryBuilder.java其中定义了must、filter、should、must_not四个子句的解析字段。Term 与 Terms 查询精确匹配的利器term查询会不分词地匹配倒排索引中的完整词条适合keyword类型字段{ term: { status: on_sale } }⚠️ 新手最大陷阱对text类型字段使用term查询常匹配不到结果因为 text 字段经过了分词。此时应改用match查询或对text字段的.keyword子字段做 term 查询。terms是 term 的批量版匹配多个值中的任意一个相当于 SQL 的IN{ terms: { category: [手机, 平板, 笔记本] } }相关源码TermQueryBuilder.java 和 BaseTermQueryBuilder.javaterms 查询的公共基类。Range 查询搞定价格与时间区间range查询用于数值、日期等可排序字段的区间判断支持 4 个边界gte大于等于gt大于lte小于等于lt小于{ range: { created_at: { gte: 2025-01-01, lt: 2025-09-20 } } }还可以用format参数指定日期格式。时间范围过滤同样建议放入 bool 的filter子句中。实现见 RangeQueryBuilder.java。Wildcard 查询* 与 ? 的模糊匹配wildcard查询支持*任意字符序列和?单个字符通配符区分大小写适合少量数据的模糊检索{ wildcard: { product_name: smart_phone* } } 性能提示后缀通配*abc效率较低尽量避免已知前缀时优先用 PrefixQueryBuilder.java 对应的prefix查询数据量大时建议改用全文match或fuzzy查询源码位于 WildcardQueryBuilder.java。Match 与 Match Phrase 查询全文搜索的首选match查询会对输入文本分词后再匹配是搜索框场景的标准答案{ match: { title: 无线蓝牙耳机 } }match_phrase要求词按顺序连续出现适合短语精确检索还支持slop参数容忍少量间隔{ match_phrase: { description: 降噪 蓝牙 耳机, slop: 3 } }实现分别见 MatchQueryBuilder.java 与 MatchPhraseQueryBuilder.java。三大轻量级查询match_all、exists、idsmatch_all——匹配所有文档常用作基准查询或只看过滤条件{ match_all: {} }exists——判断字段是否存在且非空OpenSearch 中null不会存入索引所以存在性判断很实用{ exists: { field: email } }ids——按文档_id批量取回数据比逐条 get 快得多{ ids: { values: [1, 2, 5, 10] } }对应源码MatchAllQueryBuilder.java、ExistsQueryBuilder.java、IdsQueryBuilder.java。最快上手一个综合实战案例下面这个请求组合了 6 种查询——搜索华为 手机、价格在 1000-5000、状态在售、标题含 5G 加分并按相关性排序取前 20 条GET my_phone_index/_search { from: 0, size: 20, query: { bool: { must: [{ match: { title: 华为 手机 } }], filter: [ { range: { price: { gte: 1000, lte: 5000 } } }, { term: { status: on_sale } } ], should: [{ wildcard: { tags: 5G* } }] } } }想学习更多真实 DSL 写法可以参考项目中的 REST API 测试用例 rest-api-spec/ 目录。新手避坑清单5 个高频错误text 字段用了 termtext 字段被分词term 查不到 → 改用match或.keyword子字段filter 与 must 混用纯过滤条件放must会额外计算评分 → 放filter更快wildcard 开头加*前缀通配无法利用索引性能差match_phrase 忘了 slop词序稍有出入就查不到适当设置 slop 容错exists 用于判断 nullOpenSearch 不索引 null 值exists 天然能过滤空值字段总结你想做什么选哪个查询组合多条件bool精确值 / 多值过滤term/terms价格、时间区间range通配模糊匹配wildcard搜索框关键词match短语精确匹配match_phrase取全部 / 判空 / 按 ID 取数match_all/exists/ids掌握这 10 大 OpenSearch 查询类型你就能组合出几乎所有业务需要的搜索语句。想要继续深入建议从 server/src/main/java/org/opensearch/index/query/QueryBuilders.java 入手它是所有查询构建器的统一工厂入口更多进阶玩法脚本查询、地理查询、嵌套查询等也都能在该目录中找到对应实现。【免费下载链接】OpenSearch Open source distributed and RESTful search engine.项目地址: https://gitcode.com/gh_mirrors/op/OpenSearch创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表