如何更新Postgresql的Jsonb数组
如何更新Postgresql的Jsonb数组
假设你决定将数据以json或者jsonb的形式存储在数据库中,然后发现你刚刚给自己制造了新的问题,而这些问题是以前没有的。
jsonb是一个强大的工具,但它也有一定的代价,因为你需要调整查询和处理数据的方式。
而且将整个jsonb对象加载到内存中,用你喜欢的编程语言进行转换,然后将其保存回数据库,这并不罕见。但是,你刚刚创造了另一个问题:性能瓶颈和资源浪费。
在这篇文章中,我们来看看如何通过一次查询来更新数组内对象的特定值。
假设你正在实现一个为每个客户存储动态联系人功能,那么你就会想到将联系人存储为jsonb列,因为他们是动态的,因此使用非关系型数据结构是有意义的。
然后创建一个带有jsonb列联系人,并在其中插入一些数据。
create table customers (name varchar(256), contacts jsonb);insert into customers (name, contacts) values ('Jimi','[{"type": "phone", "value": "+1-202-555-0105"},{"type": "email", "value": "jimi@gmail.com"}]'
);insert into customers (name, contacts) values ('Janis','[{"type": "email", "value": "janis@gmail.com"}]'
);
看起来很简单,但是如何更新特定的联系人信息?如何更改jimi的电子邮件或者janis的电话?
幸运的是,PostgreSQL提供了json_set
函数。函数原型:
jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean])
给定一个jsonb列,可以在指定的路径上设置一个新值。
select jsonb_set('[{"type": "phone", "value": "+1-202-555-0105"},{"type": "email", "value": "jimi@gmail.com"}]','{1,value}','"jimi.hendrix@gmail.com"',false
);select jsonb_set('[{"type": "email", "value": "janis@gmail.com"}]','{0,value}','"janis.joplin@gmail.com"',false
);
jsonb_set
函数的第一个参数为jsonb数据对象,第二个参数路径,在上面的例子中,{1,value}
为数组中索引为1的元素,并且属性是value
字段的,最后一个参数是对路径中选择的字段进行赋值。
根据这样的规则,那么第一个sql语句就是修改jimi的邮箱,而第二个sql语句就是修改janis的电子邮箱。
上面返回的结果是:
[{"type":"phone","value":"+1-202-555-0105"},{"type":"email","value":"jimi.hendrix@gmail.com"}]
[{"type":"email","value":"janis.joplin@gmail.com"}]
如果现在你认为这样就完事了,那就是你太Too young! Too simple!。
非关系型数据库的问题在于它们是动态的,这也是使用jsonb的原因之一,但是这就带来了一个问题,例如上面的案例,jimi的邮箱对象在数组中的索引是1,janis的邮箱对象在数组中索引是0,而另外的一条数据很可能是不同的数组,其索引也不一样,那么如何确定每个联系人的邮箱所在数组的索引?
答案 是对数组中的元素进行排序,并获得索引。
select index-1 as indexfrom customers,jsonb_array_elements(contacts) with ordinality arr(contact, index)where contact->>'type' = 'email'and name = 'Jimi';
该查询会返回1,这是jimi联系人的电子邮件对象索引。
现在万事俱备,只欠东风!我们把查询和更改步骤合并。
with contact_email as (select ('{'||index-1||',value}')::text[] as pathfrom customers,jsonb_array_elements(contacts) with ordinality arr(contact, index)where contact->>'type' = 'email'and name = 'Jimi'
)
update customersset contacts = jsonb_set(contacts, contact_email.path, '"jimi.hendrix@gmail.com"', false)from contact_emailwhere name = 'Jimi';
这个sql中最重要的部分就是with
,这是一个强大的命令,但对于这个例子来说,你可以把它看成是“储存变量”功能,with最后的结果都储存在contact_email变量内,其中就包含需要更新的路径,也就是jimi的邮箱路径。
下面再稍微详细介绍一下:
(‘{‘||index-1||’,value}’)::text[] as path
这一段是在建立路径{1, value}
,但是要转换成text[]
类型,因为jsonb_set函数需要这个类型。
如何更新Postgresql的Jsonb数组相关推荐
- Mybatis调用PostgreSQL存储过程实现数组入参传递
前言 项目中用到了Mybatis调用PostgreSQL存储过程(自定义函数)相关操作,由于PostgreSQL自带数组类型,所以有一个自定义函数的入参就是一个int数组,形如: CREATE OR ...
- PostgreSQL 多重含义数组检索与条件过滤 (标签1:属性, 标签n:属性) - 包括UPSERT操作如何修改数组、追加数组元素
摘要: 标签 PostgreSQL , 多重函数数组 , UDF索引 , 过滤 , 文本处理 背景 PG的数组类型,被广泛应用于 画像系统 , 标签系统. 在一些业务重建中,对数组内容的定义往往包含了 ...
- golang操作postgresql数据库jsonb类型
golang操作postgresql数据库jsonb类型 本文以案例为主,少言,自悟. 推荐一个测试sql的网站 SQL操作 // 创建一个带有jsonb列的表 CREATE TABLE items ...
- PostgreSQL jsonb 数组的增删改查
有时候我们需要使用PostgreSQL这种结构化数据库来存储一些非结构化数据,PostgreSQL恰好又提供了json这种数据类型,这里我们来简单介绍使用jsonb的一些常见操作. PostgreSQ ...
- mongo更新数组字段_更新mongodb中嵌套数组中的几个字段(使用pymongo)
我正在尝试更新数组内数组中的一些字段 示例文档如下:{ id: 987654321 tweets: [ { text: "RT @947FreshFM: A vigil will be he ...
- PostgreSQL处理jsonb中的arrays of array 类型
一.提出问题 在postgre数据库,遇到了数组内嵌套数组的jsonb存储格式,如下: SELECT * FROM public.keyword_trend 查询结果: 其中,history一栏[[& ...
- PostgreSQL中JSONB的索引
JSONB类型的列上可以直接建索引,支持BTree索引和GIN索引.其中,GIN索引可以高效的从JSONB内部的key/value对中搜索数据,因此JSONB类型上常用GIN索引. JSONB上创建G ...
- jsonb 查询_如何使用IN运算符查询jsonb数组
小编典典 简短答案 您可以jsonb_array_elements()在横向联接中使用该函数,并value在WHERE子句中的复杂表达式中使用其结果: SELECT t.* FROM test t C ...
- postgresql 遍历字符串数组_每日一道编程题(348):1005.K次取反后最大化的数组和...
1005.K次取反后最大化的数组和 每日编程中遇到任何疑问.意见.建议请公众号留言或直接撩Q474356284(备注每日编程) 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 ...
最新文章
- linux下压缩工具总结与使用(参考私房菜)
- 解决远程连接超过最大连接数问题
- matlab crf 工具包,python调用CRF++工具包
- 如何实现手游app瘦身?
- [转]c#调用API截图
- 雷达的工作原理示意图_电磁阀的构成和工作原理示意图
- 07.30《jQuery》——1.1DOM对和jQuery对象的转化
- 工作总结 EntityFramework中出现DateTime2异常的完美解决办法
- django-添加学生的制作-模块的封装
- android http 416,HTTP 416 错误 – 所请求的范围无法满足 (Requested Range not satisfiable)...
- inquirer:命令行中与用户进行交互的js库
- 企业微信代开发获取应用Secret
- apng java,免费的APNG、WebP格式转换工具-iSparta
- 2019“智汇科学城”光明区创新企业投融资路演在招商局智慧城顺利举办
- C++与C#相比,哪个更适合开发大型游戏?
- cisco配置主机计算机连接,思科交换机路由器 连接配置步骤
- html中repeat的作用,深入探究CSS repeat()函数知识及用法
- javaWEB——主页面新闻展示删除查看修改主题绑定
- UF2.0、O4、UFT、TA众明星背后的秘密
- 无需QQ密保直接修改QQ密码
热门文章
- BugkuCTF-WEB题文件包含
- c 调用mysql密码为空_C语言连MySQL - osc_srnunz15的个人空间 - OSCHINA - 中文开源技术交流社区...
- matlab 计算汉明距_matlab实现滑动平均滤波
- mysql查看版本号_十分钟了解MySQL事务机制
- [LCP28] 采购方案
- centos 使用java_如何在CentOS 8上安装Java
- matlab 遗传优化算法_转载 | 遗传算法解决TSP问题的MATLAB实现
- gcc编译器java_「gcc编译器下载」gcc编译器下载各版本下载 - seo实验室
- 软件设计师c语言算法皇后,软件设计师历年试题-算法.ppt
- JAVA的数据类型有哪些?