业务数据都是存放在内部数据库JSONB字段里面,如何有效地访问JSON里面的指定内容呢?
$product.find({ "x.姓名": "张三", "y.审核.日期": "2025-06-06" }, { select: "x.姓名, wx.headimgurl 头像, x.成绩, y.审核.审核人" })
通常业务数据都是存放在x
里面的,可以省略x.
。$product.find({ 性别: "男", 年龄: { $gt: 25 } }, { select: "姓名, 成绩.数学, wx.headimgurl 头像" })
Postgre是不区分大小写标识符的,它会将所有未加引号的标识符在内部转换为小写存储,所以含有大写字母的字段需要额外用双引号引起来。建议避免使用大写字母,用中文更加简洁易懂。
$product.find({ type: "审批", 'y."approvedDate"': today() }, { select: 'y."approvedBy" 审批人' })
$product.find({ type: "报销", "审批[0].日期": today() })
:查看今天开始审批的报销。
$product.find({ type: "店铺", "管理员[*]": $c.me.id })
:查找我管理的店铺列表。店铺管理员是个数组,星号是通配符,表示数组内的任一项。$product.find({ type: "凭证", "分录[*].借方" : { $gt: 100 } })
:查找借方金额大于100元的凭证。凭证分录是个对象数组,每项有科目/摘要/借方/贷方金额。
$product.find({ "项目.*.姓名": $c.me.姓名 })
:查找我所在的项目列表。星号是通配符,表示项目内的任一项目名。
Postgres用->
访问JSONB内部结构的,返回的JSONB类型(不管它的原本属性值是什么类型);而->>则
返回文本类型。
对于复杂的复合字段(带有空格/函数),平台不做额外转换,将原样传给数据库执行,此时就需要用到数据库原生的访问符了。注意,字段需要单引号括起来。{ select: "count(*) 数量, array_agg(distinct x->'姓名') 姓名" }
{ select: "*, lag(销售额, 1) over(partition by x->'产品名称' order by x->'年月') 上月销售额" }
{ select: "学生, case x->>'科目' when '语文' then (x->'成绩')::int else 0 end 语文, case x->>'科目' when '数学' then (x->'成绩')::int else 0 end 数学" }
对于深路径,使用#>或#>>更简练,字段里的各个键/数组下标放在花括号里用逗号隔开。{ select: "x#>'{日志,0,日期}' 日期" }
:获取第一条日志的日期。