Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从JSON[]数组中删除PostgreSQL中的已知元素?

如何从JSON[]数组中删除PostgreSQL中的已知元素?
EN

Database Administration用户
提问于 2014-05-08 05:36:13
回答 1查看 22.2K关注 0票数 8

关于在PostgreSQL中使用JSON数据类型,我面临一个问题。我试图实现在DB中存储一个非规范化的Java模型。该模型具有复杂对象的列表。因此,我决定在本机PostgreSQL数组中将其建模为JSON。

这是我的表创建语句的简化片段:

代码语言:javascript
运行
AI代码解释
复制
CREATE TABLE test.persons
(
  id UUID,
  firstName TEXT,
  lastName TEXT,
  communicationData JSON[],
  CONSTRAINT pk_person PRIMARY KEY (id)
);

正如您所看到的,它是一个在JSON中具有通信数据对象列表的人。其中一个对象可能如下所示:

代码语言:javascript
运行
AI代码解释
复制
{"value" : "03334/254147", "typeId" : "ea4e7d7e-7b87-4628-ba50-6a5f6e63dbf6"}

我可以使用PostgreSQL的array_append轻松地将这样的JSON对象附加到数组中。但是,我无法从数组中删除一个已知值。考虑一下f.e。这个SQL语句是:

代码语言:javascript
运行
AI代码解释
复制
UPDATE test.persons
SET communicationData = array_remove(
      communicationData, 
      '{"value" : "03334/254147", "typeId" : "ea4e7d7e-7b87-4628-ba50-6a5f6e63dbf6"}'::JSON
    )
WHERE id = 'f671eb6a-d603-11e3-bf6f-07ba007d953d';

这在ERROR: could not identify an equality operator for type json中失败了。您知道如何从JSON数组中删除一个已知值吗?也可以按位置移除数组中的位置,因为我知道.

PostgreSQL版本为9.3.4。

EN

回答 1

Database Administration用户

回答已采纳

发布于 2014-05-08 07:03:17

jsonb in Postgres 9.4或更高版本

考虑Postgres 9.4或更高版本中的jsonb数据类型。结尾的'b‘代表’二进制‘。除其他外,还有一个相等运算符(=)为jsonb。大多数人都会想要转换。

关于jsonb的博客.

json

没有为数据类型=定义json操作符,因为没有为整个json值建立相等的定义良好的方法。但请看下面。

您可以转换为text,然后使用=运算符。这是短的,但只有当您的文本表示恰好匹配时才能工作。本质上不可靠,除了角落的情况。请参见:

或者您可以使用unnest数组并使用->>运算符 ..。get JSON object field as text和比较各个字段。

测试表

2行:第一行类似于问题,第二行具有简单的值。

代码语言:javascript
运行
AI代码解释
复制
CREATE TABLE tbl (
   tbl_id int PRIMARY KEY
 , jar    json[]
);

INSERT INTO t VALUES
   (1, '{"{\"value\" : \"03334/254146\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f5\"}"
        ,"{\"value\" : \"03334/254147\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f6\"}"
        ,"{\"value\" : \"03334/254148\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f7\"}"}')

 , (2, '{"{\"value\" : \"a\", \"typeId\" : \"x\"}"
        ,"{\"value\" : \"b\", \"typeId\" : \"y\"}"
        ,"{\"value\" : \"c\", \"typeId\" : \"z\"}"}');

Demos

演示1

您可以将array_remove()text表示(不可靠)结合使用。

代码语言:javascript
运行
AI代码解释
复制
SELECT tbl_id
     , jar, array_length(jar, 1) AS jar_len
     , jar::text[] AS t, array_length(jar::text[], 1) AS t_len
     , array_remove(jar::text[], '{"value" : "03334/254147", "typeId" : "ea4e7d7e-7b87-4628-ba50-f6"}'::text) AS t_result
     , array_remove(jar::text[], '{"value" : "03334/254147", "typeId" : "ea4e7d7e-7b87-4628-ba50-f6"}'::text)::json[] AS j_result
FROM   tbl;

演示2

撤消单个元素的数组和测试字段。

代码语言:javascript
运行
AI代码解释
复制
SELECT tbl_id, array_agg(j) AS j_new
FROM   tbl, unnest(jar) AS j   -- LATERAL JOIN
WHERE  j->>'value' <> '03334/254146'
AND    j->>'typeId' <> 'ea4e7d7e-7b87-4628-ba50-6a5f6e63dbf5'
GROUP  BY 1;

演示3

行类型的替代测试。

代码语言:javascript
运行
AI代码解释
复制
SELECT tbl_id, array_agg(j) AS j_new
FROM   tbl, unnest(jar) AS j   -- LATERAL JOIN
WHERE  (j->>'value', j->>'typeId') NOT IN (
         ('03334/254146', 'ea4e7d7e-7b87-4628-ba50-6a5f6e63dbf5')
        ,('a', 'x')
       )
GROUP  BY 1;

UPDATE按要求提供

最后,您可以这样实现您的UPDATE

代码语言:javascript
运行
AI代码解释
复制
UPDATE tbl t
SET    jar = j.jar
FROM   tbl t1
CROSS  JOIN LATERAL (
   SELECT ARRAY(
      SELECT j
      FROM   unnest(t1.jar) AS j  -- LATERAL JOIN
      WHERE  j->>'value'  <> 'a'
      AND    j->>'typeId' <> 'x'
      ) AS jar
   ) j
WHERE  t1.tbl_id = 2              -- only relevant rows
AND    t1.tbl_id = t.tbl_id;

db<>fiddle 这里

关于隐式LATERAL JOIN

关于取消嵌套数组:

DB设计

为了简化您的情况,请考虑一个规范化的模式:一个单独的json值表(而不是数组列),它与主表的关系为n:1。

票数 12
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/64759

复制
相关文章
Neo4J:创建带关系的节点
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
程裕强
2019/10/22
2.5K0
Neo4J:创建带关系的节点
Neo4J:Apoc插件的下载与安装
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
程裕强
2019/10/24
3K0
Neo4J:Apoc插件的下载与安装
Traefik 开发中间件插件(六)
Traefik插件架构使开发人员可以轻松创建新插件、修改现有插件以及与 Traefik 社区共享插件。 Traefik 插件是使用Go 语言开发的,而Traefik中间件插件只是一个Go 包,它提供了一个http.Handler执行特定请求和响应处理的包。 然而,插件并没有被预编译和链接,而是由Yaegi 动态执行,Yaegi是一个嵌入在 Traefik 应用程序代理中的 Go 解释器。 这意味着插件不需要编译,也不需要复杂的工具链来开始。开发 Traefik 插件的过程可与 Web 浏览器扩展相媲美。 插件可能会以不希望的方式修改 Traefik 的行为.向生产 Traefik 实例添加新插件时要小心.
rxg456
2022/05/15
1.1K0
Cordova 创建 Demo插件
MyPluginName.js JavaScript接口,用于插件与混合应用的接口。
acc8226
2022/05/17
7300
Neo4j 查询已经创建的索引与约束
在Neo4j 2.0之后为cypher语法增加了一些类似于DDL的语法,能够自己创建索引,约束等等。
用户3148308
2018/09/13
2.2K0
Neo4j 查询已经创建的索引与约束
python操作neo4j创建知识图谱模板
数据: 购买方名称 销售方名称 金额 山东高速集团有限公司电子收费中心 哈尔滨告诉公司 2000W级别交易 湖南道岳高速公路实业有限公司 湖北阿深南高速公路发展有限公司 2000W级别交易 湖南道岳高速公路实业有限公司 湖北阿深南高速公路发展有限公司 100W级别交易 湖南道岳高速公路实业有限公司 湖北阿深南高速公路发展有限公司 2000W级别交易 山东高速集团有限公司电子收费中心 湖北阿深南高速公路发展有限公司 2000W级别交易 山东高速集团有限公司电子收费中心 湖北阿深南高速公路发展有限公司 2000
西西嘛呦
2021/11/24
6560
python操作neo4j创建知识图谱模板
【Flutter】开发 Flutter 包和插件 ( Flutter 包和插件简介 | 创建 Flutter 插件 | 创建 Dart 包 )
" Flutter 包 " 包含 pubspec.yaml 和 lib 代码目录 ;
韩曙亮
2023/03/29
1.7K0
【Flutter】开发 Flutter 包和插件 ( Flutter 包和插件简介 | 创建 Flutter 插件 | 创建 Dart 包 )
使用podspec创建iOS插件
在WWDC 2014全球开发者大会上,苹果开放了动态库、App Extension等全新的功能,这为iOS插件化开发带来了可能。在iOS开发中,动态库是iOS提供的一种资源打包方式,可以将代码文件、头文件、资源文件和说明文档等集中在一起,并且可以在运行时进行动态加载。
xiangzhihong
2022/11/30
2930
Qt插件创建及加载
上次我们是直接在Qt 自带的例子基础上做的修改,直接运行。我们的插件需要继承Qt 的Style插件,之后重新实现自己想要实现的部分。在主程序中直接通过QApplication::setStyle进行调用。
用户5908113
2019/12/19
1.9K0
学习 | egg.js 中间件和插件
[wp_editor_md_7ee9bb85a07c7f001ca0a8ed9432368c.jpg]
mySoul
2020/07/22
9700
neo4j APOC插件安装以及Yelp示例数据导入
APOC库包含许多(约450个)程序和函数,可帮助处理数据集成,图算法或数据转换等
lovelife110
2021/01/14
1.3K0
WordPress插件开发教程一:创建、停用、删除插件
在wp-content/plugins创建一个文件夹,命名最好加前缀,WordPress官方现在应该收录了有五万多的插件,所以要起一个特殊的名称,防止插件和别人重名
沈唁
2019/05/21
8940
WordPress插件开发教程二:创建插件菜单和插件设置页面
如果我们的插件设置很简单,只需一个或两个参数的时候,可以考虑添加到设置->常规的页面中,这样就无须再新增页面了
沈唁
2019/05/21
1.2K0
使用Python在Neo4j中创建图数据库
图数据库的一个最常见的问题是如何将数据存入数据库。在上一篇文章中,我展示了如何使用通过Docker设置的Neo4j浏览器UI以几种不同的方式之一实现这一点。
磐创AI
2021/05/07
5.7K0
使用Python在Neo4j中创建图数据库
Neo4j 系列(1) —— 初识 Neo4j
图数据库是基于图论实现的一种NoSQL数据库,其数据存储结构和数据查询方式都是以图论为基础的,图数据库主要用于存储更多的连接数据
求和小熊猫
2021/12/06
3K0
eclipse插件创建本地git仓库
由于我的eclipse是写书时最新版本,eclipse4.7版本,自带git,无需安装。既然我们本地机器里还没有任何仓库,在eclipse中选择 一个项目,右键->Team->Share Project, 选择 Git,在下图中点击Create按钮(找个自己心仪的目录),本地仓库即可创建成功(如果过去你已经创建过仓库,直接点击右边的"下箭头"即可,也可以 从preferences/team/git中找到仓库位置)。马克-to-win:像我一样设置完成,就点finish按钮。这样,你的项目就会从workspace移动到git 仓库里,底下有个选项是"use or create repository in parent folder of project",eclipse推荐是不勾,这样你的项目就会拷贝到git目录下,看我的参考目录下有篇博文援引英文的刊物的意见。勾上后,你的项目还 在workspace里,git配置文件拷进你的项目文件夹。
马克java社区
2019/08/14
8490
eclipse插件创建本地git仓库
支持插件的消息中间件【msg broker with plugin】
支持插件的消息中间件 msg broker with plugin Msg Broker概念: msg broker是实现application 之间互通讯的组件。通常为实现application之间的解耦,消息都是通过msg broker完成转发。application只需知道其他applicatipn的逻辑名称,而不需要知道对方的具体位置。Broker中维护一个查找表,记录着哪个application注册在此逻辑名称之下,所以消息总是会被正确的投递到目的地。 msg broker不限于1-1的转发,也支
知然
2018/03/09
1.6K0
支持插件的消息中间件【msg broker with plugin】
neo4j服务端算法插件安装以及简单用法
neo4j依赖jdk环境,本例中neo4j-community-3.5.8、jdk1.8
lovelife110
2021/01/14
1.1K0
neo4j服务端算法插件安装以及简单用法
用Publish创建博客(三)——插件开发
在用Publish创建博客(一)——入门[4]中我们介绍过Publish有两个Content概念。其中PublishingContext作为根容器包含了你网站项目的全部信息(Site、Section、Item、Page等)。在对Publish进行的大多数扩展开发时,都需要和PublishingContext打交道。不仅通过它来获取数据,而且如果要对现有数据进行改动或者添加新的Item、Page时(在Content中采用不创建markdown文件的方式)也必须要调用其提供的方法。比如mutateAllSections、addItem等。
东坡肘子
2022/07/28
4600
用Publish创建博客(三)——插件开发
构建技术中台——新技术验证与应用
2020年,普元基于自身技术中台所需,验证了一些新技术并加以使用,旨在不断提升技术中台的综合能力。通过这次机会,将我们团队所做的一些技术验证和使用方式与大家分享,希望在公司内外建立更好的技术沟通,同时提出技术中台的下一步发展想法,供大家参考指正。
yuanyi928
2020/12/11
8470
构建技术中台——新技术验证与应用

相似问题

如何在neo4j中创建插件?

33

neo4j - graphaware插件

14

Neo4j插件@Name

11

Django中间件插件与视图

12

如何在neo4j中创建服务器插件

310
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档