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

使用Knex/Postgres构建嵌套JSON查询的更新报错求助

解决Knex更新嵌套JSON字段的问题

问题分析

你遇到的两个错误核心原因如下:

  1. whereRaw用->运算符报错:->返回的是JSON类型,直接与字符串/未知类型比较会触发类型不匹配,PostgreSQL无法识别json = unknown的运算符。
  2. whereJsonPath报错:该方法依赖PostgreSQL 12+引入的jsonb_path_query_first函数,若你的location列是JSON类型而非JSONB,或数据库版本低于12,就会出现这个错误。

解决方案

方案1:修正whereRaw写法(兼容所有PostgreSQL版本)

根据你的匹配需求分场景处理:

场景A:匹配完整的location对象

将请求体中的location转为JSON字符串,再强制转为JSON类型与列值匹配:

const targetLocation = requestBody.location;

knex('assets')
  .update({ status: 'Pending Transfer' })
  .whereRaw('location = ?::json', [JSON.stringify(targetLocation)])

场景B:匹配嵌套字段(如site或site_loc下的属性)

用->>运算符提取JSON字段的文本值,再与目标值比较:

// 匹配site字段
knex('assets')
  .update({ status: 'Pending Transfer' })
  .whereRaw('location->>? = ?', ['site', targetLocation.site])

// 匹配site_loc下的shelf字段
knex('assets')
  .update({ status: 'Pending Transfer' })
  .whereRaw('location->\'site_loc\'->>? = ?', ['shelf', targetLocation.site_loc.shelf])

方案2:使用whereJsonPath(需PostgreSQL 12+)

如果数据库版本≥12,且location列是JSONB类型,直接使用:

knex('assets')
  .update({ status: 'Pending Transfer' })
  .whereJsonPath('location', '$.site', '=', targetLocation.site)

若location列是JSON类型,先转为JSONB再查询:

knex('assets')
  .update({ status: 'Pending Transfer' })
  .whereJsonPath('location::jsonb', '$.site_loc.shelf', '=', targetLocation.site_loc.shelf)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:45:59