Laravel Eloquent如何实现MySQL JSON多语言字段的不区分大小写查询
问题根因
你之前的两种写法失败主要有三个原因:
- MySQL中JSON字段的
字段->键名访问语法是Laravel查询构造器的语法糖,直接拼接进原生函数/原生SQL时不会被自动解析为正确的JSON提取逻辑 - 第二种写法错误给字段名加上了单引号,导致MySQL将其识别为普通字符串,而非读取字段对应的值
- 代码存在变量名拼写错误,比如
$procut_name、$asset_local_name,也会导致查询逻辑异常
可行解决方案
方案1:whereRaw写法(兼容所有支持JSON功能的MySQL版本)
优先使用参数绑定避免SQL注入风险:
$locale = $this->subdomain; $searchKeyword = strtolower($product_name); $product = Product::whereRaw( "LOWER(JSON_UNQUOTE(JSON_EXTRACT(name, '$.?'))) LIKE ?", [$locale, "%{$searchKeyword}%"] )->first();
如果你的MySQL版本在5.7.13及以上,支持->>JSON提取运算符,可以简化写法:
$locale = $this->subdomain; $searchKeyword = strtolower($product_name); $product = Product::whereRaw( "LOWER(name->>'$.{$locale}') LIKE ?", ["%{$searchKeyword}%"] )->first();
方案2:Laravel原生查询语法(写法最简洁)
利用MySQL本身大小写不敏感的排序规则实现忽略大小写匹配,不需要手动转大小写:
$product = Product::where("name->{$this->subdomain}", 'like', "%{$product_name}%") ->collate('utf8mb4_general_ci') ->first();
额外注意事项
- 你定义的路由
/proudct/{product_name}存在拼写错误,正确拼写应为/product/{product_name} - 如果产品数据量较大,建议给JSON字段对应locale的值创建生成列并加索引,避免模糊查询触发全表扫描拖慢性能
内容的提问来源于stack exchange,提问作者Gonras Karols
相关产品推荐
相关产品推荐

