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

GORM查询PostgreSQL含指定元素的JSON数组字段问题

解决GORM+PostgreSQL JSON字段包含查询的问题

核心问题分析

你之前的写法存在两个关键问题:

  • 手动拼接JSON字符串极易出现引号转义错误,还存在SQL注入风险
  • 使用attributes ->> 'email' = '[\"%v\"]'是直接匹配数组的完整字符串形式,只有当email数组完全等于目标数组时才会命中,无法实现"包含单个元素"的查询需求

正确实现方案

方案1:直接使用PostgreSQL的@>操作符(推荐)

复用SQL编辑器中验证有效的@>包含操作符,配合GORM参数绑定避免拼接错误:

import "encoding/json"

// 构造合法的查询JSON结构
email := "eee@ccc.cc"
queryCondition, _ := json.Marshal(map[string][]string{"email": {email}})

var authors []Author
// 执行查询
db.Where("attributes @> ?", string(queryCondition)).Find(&authors)

通过json.Marshal自动生成标准JSON字符串,彻底规避手动转义引号的问题,同时保证查询逻辑与SQL编辑器完全一致。

方案2:使用JSON数组元素展开查询

如果需要更灵活的数组元素匹配逻辑,可以用jsonb_array_elements(针对jsonb类型)或json_array_elements(针对json类型)展开数组后匹配:

var authors []Author
email := "eee@ccc.cc"
db.Where("EXISTS (SELECT 1 FROM jsonb_array_elements(attributes->'email') AS elem WHERE elem::text = ?)", "\""+email+"\"").Find(&authors)

注:由于数组元素是字符串类型,elem::text会带引号,因此需要给目标邮箱字符串手动添加引号。

方案3:使用GORM Raw查询(正确参数绑定版)

如果必须使用Raw查询,不要手动拼接SQL,通过参数绑定传递查询条件:

import "encoding/json"

email := "eee@ccc.cc"
queryCondition, _ := json.Marshal(map[string][]string{"email": {email}})

var authors []Author
db.Raw("SELECT * FROM authors WHERE attributes @> ?", string(queryCondition)).Scan(&authors)

额外注意事项

  • 确认attributes字段类型为json或jsonb(推荐用jsonb,查询性能更优)
  • 禁止使用fmt.Sprintf拼接SQL语句,既容易出错,又会引入SQL注入风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:32:03