You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel whereJsonContains用数组匹配JSON字段返回空集合的解决方法

解决Laravel whereJsonContains匹配JSON字符串值的类型与多值问题

看起来你遇到的问题核心是MySQL JSON函数的类型敏感性,以及对whereJsonContains处理数组参数的语义理解偏差,咱们一步步拆解解决:

为什么之前的写法无效?

  1. 类型不匹配:你的payload->ProductCode->id存储的是字符串类型的"1",但你用数值1或者数值数组[1,2,3]去匹配时,MySQL的JSON_CONTAINS函数是严格类型匹配的,字符串和数值不会被视为相等,所以返回空集合。
  2. 数组参数的语义误解:当你给whereJsonContains传数组时,它的语义是「匹配JSON路径对应的数组字段包含该数组的所有元素」,而你的id是单个字符串值,不是数组,所以这种写法从一开始就不符合场景。

正确的解决方案

1. 匹配单个值:确保类型一致

如果只是要匹配单个id,必须使用和数据库存储一致的字符串类型值:

// 这样就能正确返回目标记录
$myCollection = MyModel::whereJsonContains('payload->ProductCode->id', "1")->get();

2. 匹配多个值:结合JSON提取与whereIn

如果要匹配id是数组中任意一个字符串值的记录,推荐用whereIn配合原生JSON函数来实现,效率比循环orWhereJsonContains更高:

use Illuminate\Support\Facades\DB;

// 注意数组元素是字符串,和数据库存储类型一致
$targetIds = ["1", "2", "3"];

$myCollection = MyModel::whereIn(
    // 提取并移除JSON字符串的引号,得到原始字符串值
    DB::raw('JSON_UNQUOTE(JSON_EXTRACT(payload, "$.ProductCode.id"))'),
    $targetIds
)->get();

3. 备选:循环添加orWhereJsonContains(适合小批量值)

如果你的目标数组元素不多,也可以用循环逐个添加orWhereJsonContains条件:

$targetIds = ["1", "2", "3"];

$query = MyModel::query();
foreach ($targetIds as $id) {
    $query->orWhereJsonContains('payload->ProductCode->id', $id);
}

$myCollection = $query->get();

额外提示

如果你的业务场景允许,也可以考虑在存入数据库时,将ProductCode->id存储为数值类型,这样后续匹配时就不用纠结类型问题,但这需要修改数据结构和写入逻辑,需要根据实际情况权衡。

内容的提问来源于stack exchange,提问作者mykoman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 22:37:30