使用Knex/Postgres构建嵌套JSON查询的更新报错求助
解决Knex更新嵌套JSON字段的问题
问题分析
你遇到的两个错误核心原因如下:
whereRaw用->运算符报错:->返回的是JSON类型,直接与字符串/未知类型比较会触发类型不匹配,PostgreSQL无法识别json = unknown的运算符。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
相关产品推荐
相关产品推荐

