如何解决Laravel Eloquent中JSON数据Like语句的大小写敏感问题?
解决Laravel Eloquent JSON字段大小写不敏感模糊查询问题
这个问题我之前在项目里也踩过坑!核心原因是MySQL对JSON字段提取出的字符串默认会按区分大小写的规则进行匹配,而你用的普通like查询没有做大小写统一处理,所以只有当搜索关键词和存储值的大小写完全一致时才会命中结果。
下面给你几个可行的解决方案,按简洁度排序:
方案1:使用MySQL的LOWER()函数统一大小写(推荐)
利用MySQL的字符串转小写函数,把JSON字段里的owner值和你的搜索关键词都转成小写后再匹配。Laravel里可以用whereRaw来实现,结合MySQL 5.7+支持的->>语法(快速提取并去除JSON字符串的引号):
$lowerReceipt = strtolower($receipt); Order::whereRaw('LOWER(information->>"$.owner") LIKE ?', ["%{$lowerReceipt}%"]) ->paginate(5);
解释:
information->>"$.owner":等价于JSON_UNQUOTE(JSON_EXTRACT(information, "$.owner")),直接取出JSON字段里owner的纯字符串值LOWER():把取出的字符串转成小写strtolower($receipt):把用户输入的搜索关键词也转成小写,确保两边大小写统一
方案2:用原生JSON函数实现(兼容更早版本MySQL)
如果你的MySQL版本不支持->>语法,可以用JSON_EXTRACT和JSON_UNQUOTE组合:
$lowerReceipt = strtolower($receipt); Order::whereRaw('LOWER(JSON_UNQUOTE(JSON_EXTRACT(information, "$.owner"))) LIKE ?', ["%{$lowerReceipt}%"]) ->paginate(5);
功能和方案1完全一致,只是写法更繁琐。
方案3:修改数据库collation(不推荐)
你也可以尝试修改表的collation为不区分大小写的类型(比如utf8mb4_general_ci),但这种方法有两个弊端:
- JSON字段的默认collation可能继承自表,但MySQL对JSON类型的字符串匹配逻辑不一定会完全遵循表的collation,稳定性不如函数转换
- 会影响整个表的所有字符串查询,可能破坏其他需要区分大小写的业务逻辑
额外提醒
- 记得确保
$receipt是字符串类型,避免传入非字符串值导致的意外问题 - 如果需要支持多语言特殊字符(比如带重音的字母),可以用MySQL的
LOWER(_utf8mb4 '...')或者结合COLLATE子句,但英文场景下方案1完全够用
内容的提问来源于stack exchange,提问作者moses toh
相关产品推荐
相关产品推荐

