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

Laravel嵌套JSON数据查询问题:whereJsonContains查询失效排查

问题分析与解决方案

问题根源

你查询失败的核心原因是:transaction_details数组里的place字段存储的是JSON格式的字符串(带转义符的"{\"id\":3,...}"),而非原生的嵌套JSON对象。Laravel的whereJsonContains只能直接处理原生JSON结构,无法自动解析字符串形式的JSON内容。

解决方案

根据你的需求,分两种情况处理:

情况1:可以修改数据存储结构(推荐)

如果能调整数据存入方式,将place字段的JSON字符串解码为对象后再存入数据库(确保transaction_details里的place是原生JSON对象,而非字符串),之后即可使用你最初尝试的查询语句:

$q->whereJsonContains('history_product.transaction_details', ['place' => ['id' => 3]]);

情况2:无法修改存储结构,用原生SQL查询

直接利用MySQL的JSON函数来解析字符串并查询,通过whereRaw执行原生语句:

$q->whereRaw('EXISTS (
    SELECT 1 
    FROM JSON_TABLE(
        history_product.transaction_details,
        "$[*]" COLUMNS (
            place_str TEXT PATH "$.place"
        )
    ) AS item
    WHERE JSON_UNQUOTE(JSON_EXTRACT(JSON_PARSE(item.place_str), "$.id")) = 3
)');

这段SQL的逻辑是:

  • 用JSON_TABLE把transaction_details数组拆分成单行记录
  • 取出每个记录的place字符串,用JSON_PARSE转成JSON对象
  • 提取id值并和3对比,存在匹配则返回该行数据

或者用更简洁的JSON_SEARCH写法:

$q->whereRaw('JSON_SEARCH(
    history_product.transaction_details, 
    "one", 
    "3", 
    NULL, 
    "$[*].place"
) IS NOT NULL');

注意:如果id是数值类型,需要把"3"改成3,并确保MySQL版本支持JSON_SEARCH的数值匹配(部分版本可能需要字符串形式)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:20:08