MySQL JSON_SEARCH 怎样按通配符找到 JSON 字符串路径
来源:17golang原创
时间:2026-10-23 03:59:02 288浏览 收藏
MySQL 里想从 JSON 文档中找出“值在哪个路径”,可以用 JSON_SEARCH()。它搜索的是 JSON 文档里的字符串值,返回匹配值所在的路径;把 one 换成 all,就能从单一路径切换为全部不重复路径。搜索字符串里的 % 匹配任意长度字符,_ 匹配一个字符;如果要查字面量的百分号或下划线,再使用固定的转义字符。
官方地址:https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html
排查 JSON_SEARCH 返回 NULL 时,先确认文档和搜索值不是 NULL,再检查 path 范围、字符串类型以及 %、_ 是否被当成了通配符。
先分清 one 和 all:返回值不是同一种形态
我处理这类字段时,会先决定调用方只需要一个位置,还是要把所有位置都拿回来。函数的基本形式是 JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])。one 找到一个匹配后就结束,返回一个路径字符串;all 返回所有不重复路径,多个结果会自动包装成数组。官方文档没有保证“第一个”匹配的选择,也没有保证数组中路径的顺序,所以不要把它当成稳定排序接口。
-- 构造一个包含重复关键词的文档,观察 one 与 all 的返回契约
SET @catalog = JSON_OBJECT(
'items', JSON_ARRAY(
JSON_OBJECT('name', '蓝色笔记本', 'tag', '办公'),
JSON_OBJECT('name', '蓝色文件夹', 'tag', '办公')
),
'featured', JSON_OBJECT('name', '蓝色笔记本')
);
SELECT
JSON_SEARCH(@catalog, 'one', '蓝色笔记本') AS first_path,
JSON_SEARCH(@catalog, 'all', '蓝色笔记本') AS all_paths;
这段查询的重点不是记住某个具体路径顺序,而是识别返回类型:first_path 是一个 JSON 字符串路径,all_paths 可能是包含多个路径的 JSON 数组。若业务只要判断“有没有”,可以在应用层按 NULL 与非 NULL 处理;若要继续读取每个位置,则应把数组当 JSON 结果处理,不要直接按逗号切字符串。

通配符、转义字符和搜索范围
search_str 的匹配规则和 LIKE 类似:% 可以匹配零个或多个字符,_ 只匹配一个字符。它们只作用于待搜索的字符串模式,不是 JSON path 里的层级通配符。要缩小搜索范围,可以把一个或多个 JSON path 放到参数末尾,例如只搜索数组元素中的 name 字段。
-- 只搜索 items 数组中的 name 字段,并分别演示 % 与 _
SET @catalog = JSON_OBJECT(
'items', JSON_ARRAY(
JSON_OBJECT('name', 'blue-notebook'),
JSON_OBJECT('name', 'blue-folder'),
JSON_OBJECT('name', 'red-notebook')
),
'note', 'blue-notebook'
);
SELECT
JSON_SEARCH(@catalog, 'all', 'blue%', NULL, '$.items[*].name') AS blue_names,
JSON_SEARCH(@catalog, 'all', 'red-_______', NULL, '$.items[*].name') AS red_name;
第一条模式中的 blue% 能覆盖以 blue 开头的多个字符串,第二条里的下划线数量决定了后续字符数。末尾的 $.items[*].name 让搜索不再扫描根部的 note 字段;如果 path 本身写错,函数会报路径表达式错误,而不是简单返回“没有匹配”。
如果要查一个真正的百分号或下划线,必须先约定转义字符。例如数据值是 release_2026%,可以使用反斜杠把两个符号按字面匹配。默认转义字符是反斜杠;显式传入的 escape_char 必须是编译期常量,并且只能是空字符串或单个字符。把预处理语句的 ? 当作动态转义字符传入,可能在执行时有值,但不满足这个编译期常量要求。
-- 用反斜杠保护字面量的 _ 和 %;SQL 字符串中的反斜杠按当前 SQL mode 处理
SET @release_doc = JSON_OBJECT(
'version', 'release_2026%',
'channel', 'release_2026a'
);
SELECT JSON_SEARCH(
@release_doc,
'all',
'release\\_2026\\%',
'\\',
'$'
) AS literal_path;
这里的意图是把 _ 和 % 当作普通字符,而不是让它们继续展开成模式。SQL 字符串转义和 JSON_SEARCH 的模式转义是两层规则;在客户端或预处理语句中拼接反斜杠时,要先确认最终送到 MySQL 的字符串内容。

返回 NULL 时按四层边界排查
JSON_SEARCH() 返回 NULL 不等于“SQL 语法一定错了”。官方语义包括:json_doc、search_str 或 path 参数为 NULL;path 在文档中不存在;搜索字符串没有找到。相反,JSON 文档无效、path 表达式无效、one_or_all 不是 one 或 all,通常会直接报错。
| 现象 | 优先检查 | 处理方式 |
|---|---|---|
| 返回 NULL | 输入是否为 NULL、path 是否命中、字符串是否匹配 | 逐个去掉可选 path,改用精确字符串定位范围 |
| 返回一个路径 | 是否使用了 one,或 all 只有一个匹配 | 需要全部结果时显式使用 all |
| 返回数组顺序变化 | 是否把结果顺序当成契约 | 应用层排序或按路径集合处理 |
| 报参数错误 | JSON、path、one_or_all、escape_char 是否符合约束 | 先用常量 escape_char 和简单 path 缩小问题 |
还要记住它匹配的是字符串值。数字、布尔值或对象不能因为“看起来像文本”就按同一规则命中;如果业务要按类型和值筛选,需要另选 JSON 提取或表结构设计。本文讨论的是定位路径,不是把 JSON_SEARCH 当作索引方案,也不代表给 JSON_SEARCH 加上通配符后就会自动获得索引性能。
我会怎样把 JSON_SEARCH 放进应用代码
在接口层,我会先固定搜索范围,再决定是否需要全部路径:只展示一个提示位置时使用 one,需要批量修正或审计时使用 all。如果搜索值来自用户输入,则应把输入当作数据参数处理,并明确是否允许用户使用 %、_ 这样的模式字符;如果业务只允许精确匹配,就要做字面量转义,而不是直接拼到搜索模式中。
最后再强调一次结果契约:one 的路径选择不保证顺序,all 的数组顺序也不保证稳定。要把路径写回 JSON、记录审计或生成可重复的接口响应时,先在应用层解析数组并自行排序;不要用一次返回的排列顺序推断文档内部的业务优先级。
JSON_SEARCH 能直接查数字吗?
它用于搜索字符串值。数字、布尔值或对象应使用更匹配其类型的 JSON 查询方式,不要把数字先强行拼成字符串再依赖模糊匹配。
为什么 JSON_SEARCH 返回 NULL 而 JSON 文档里明明有值?
常见原因是 path 把搜索范围限定错了、值不是字符串,或者 %、_ 的含义与预期不同。先移除可选 path,再用精确字符串逐层缩小范围。
all 返回的路径数组可以按下标直接使用吗?
可以读取数组,但不要把数组下标当作稳定业务顺序。官方不保证 all 结果数组的元素顺序,需要稳定输出时由应用层重新排序。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习