PostgreSQL查询和处理JSON数据

 更新时间:2023年11月25日 08:47:29   作者:c_zyer  
这篇文章主要给大家介绍了关于PostgreSQL查询和处理JSON数据的相关资料,需要的朋友可以参考下

前言

由于项目内使用的Postgresql 且存储了一些非结构化的json数据,里面含有统计与记录,并且有嵌套关系,所以需要了解如何查询和处理Postgresql中的JSON数据。

  • Postgresql:9.6

  • 官方文档:http://postgres.cn/docs/9.6/functions-json.html#FUNCTIONS-JSON-CREATION-TABLE

  • 一张基础订单表结构:

-- order表
"id" bigserial primary key,
"order_id" varchar(55) COLLATE "default",
"product_id" int8,
"order_json" text COLLATE "default",
"create_time" timestamp(6),

背景知识:json和jsonb 操作符

操作符右操作数类型描述例子例子结果
->int获得 JSON 数组元素(索引从 0 开始,负整数结束)‘[{“a”:“foo”},{“b”:“bar”},{“c”:“baz”}]’::json->2{“c”:“baz”}
->text通过键获得 JSON 对象域‘{“a”: {“b”:“foo”}}’::json->‘a’{“b”:“foo”}
->>int以文本形式获得 JSON 数组元素‘[1,2,3]’::json->>23
->>text以文本形式获得 JSON 对象域‘{“a”:1,“b”:2}’::json->>‘b’2
#>text[]获取在指定路径的 JSON 对象‘{“a”: {“b”:{“c”: “foo”}}}’::json#>‘{a,b}’{“c”: “foo”}
#>>text[]以文本形式获取在指定路径的 JSON 对象‘{“a”:[1,2,3],“b”:[4,5,6]}’::json#>>‘{a,2}’3

问:如何查看JSON指定的key内容?

通过::json的语法

select order_json::json->'orderBody' from order -- 对象域
select order_json::json->>'orderBody' from order -- 文本
select order_json::json#>'{orderBody}' from order -- 对象域
select order_json::json#>>'{orderBody}' from order -- 文本

还有更多的jsonb操作符和json操作函数见官方文档

问:怎么处理多层嵌套的JSON?

就是采用基本的JSON语法,注意结果是对象域还是文本,对象域可以继续取用字段,文本就不能继续查看JSON咯

select '{"sites":{"site":{"id":"1","name":"菜鸟教程","url":"www.runoob.com"}}}'::json->'sites'->'site' -- 对象域
select '{"sites":{"site":{"id":"1","name":"菜鸟教程","url":"www.runoob.com"}}}'::json->'sites'->>'site' -- 文本

问:怎么处理JSON数组呢?

也是通过JSON的基本操作先定位到数组对象所在的Key,通过key取到对应的value后直接->(0),就可以取用到对应的对象域,注意对象域和文本,转化为文本就不能够在取key和具体数据数据咯

还有很多关于json相关的方法,可以详见官方文档

select '{"sites":{"site":[{"id":"1","name":"菜鸟教程","url":"www.runoob.com"},{"id":"2","name":"菜鸟工具","url":"c.runoob.com"},{"id":"3","name":"Google","url":"www.google.com"}]}}'::json->'sites'->'site'->(0)

select '{"sites":{"site":[{"id":"1","name":"菜鸟教程","url":"www.runoob.com"},{"id":"2","name":"菜鸟工具","url":"c.runoob.com"},{"id":"3","name":"Google","url":"www.google.com"}]}}'::json->'sites'->'site'->(0)->>'id'

延伸:如何取用JSON数组的最后一个对象数据?

select json_array_length('{"sites":{"site":[{"id":"1","name":"菜鸟教程","url":"www.runoob.com"},{"id":"2","name":"菜鸟工具","url":"c.runoob.com"},{"id":"3","name":"Google","url":"www.google.com"}]}}'::json->'sites'->'site') -- 查询json数据的长度

select '{"sites":{"site":[{"id":"1","name":"菜鸟教程","url":"www.runoob.com"},{"id":"2","name":"菜鸟工具","url":"c.runoob.com"},{"id":"3","name":"Google","url":"www.google.com"}]}}'::json->'sites'->'site'->(json_array_length('{"sites":{"site":[{"id":"1","name":"菜鸟教程","url":"www.runoob.com"},{"id":"2","name":"菜鸟工具","url":"c.runoob.com"},{"id":"3","name":"Google","url":"www.google.com"}]}}'::json->'sites'->'site') -1)

问:怎么替换JSON字符串中的内容?

通过select语句先看一下官方语法

函数返回值描述例子例子结果
jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean])jsonb如果create_missing是真的 (缺省是true)并且通过path 指定部分不存在,那么返回target, 它具有path指定部分, new_value替换部分, 或者new_value添加部分。 正如路径导向的操作符,负整数出现在JSON数组结尾的path>计数中。(1)jsonb_set(‘[{“f1”:1,“f2”:null},2,null,3]’, ‘{0,f1}’,‘[2,3,4]’, false)
(2)jsonb_set(‘[{“f1”:1,“f2”:null},2]’, ‘{0,f3}’,‘[2,3,4]’)
[{“f1”:[2,3,4],“f2”:null},2,null,3]
[{“f1”: 1, “f2”: null, “f3”: [2, 3, 4]}, 2]

官方描述的挺明确:jsonb_set的方法

  • 第一位参数,需要是jsonb的对象域
  • 第二位参数,是访问对应value的path(注意这个path的语法可以是{a,b},表名key-a中的key-b,数据的话参看表格中的(2))
  • 第三位参数,就是一个新的值,来替换第一个参数中的第二个参数key的value
  • 第四个参数,如果create_missing是真的 (缺省是true)并且通过path 指定部分不存在,那么返回target, 它具有path指定部分, new_value替换部分, 或者new_value添加部分。 正如路径导向的操作符,负整数出现在JSON数组结尾的path>计数中

参照官方文档,简单的一次内容替换

select jsonb_set(order_json::jsonb,'{premsg}','test'::jsonb) from order 

那么如果是嵌套多层的JSON value可以替换吗?–可以的,语法是一样的,就是需要定位到指定的字段就可以

select jsonb_set((order_json::json->>'rspDesc')::jsonb, '{preOrder}', '"11111"'::jsonb) from order

上面是select语句,那具体的update语句怎么写呢?

语法:UPDATE 表明 set 列名 = (jsonb_set(列名::jsonb,'{key}','"value"'::jsonb)) where 条件 

update order set order_json = jsonb_set(order_json::jsonb,'{rspDesc}',(jsonb_set((event_json::json->>'rspDesc')::jsonb, '{preNumber}', '"999999999"'::jsonb)::jsonb)) -- 需要先把需要改的内容替换好,然后在整体更新替换,此时这个rspDesc是对象域格式

网上基本没有执行成功的例子,在此记录下。

总结

到此这篇关于PostgreSQL查询和处理JSON数据的文章就介绍到这了,更多相关pgSQL处理JSON数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解PostgreSQL提升批量数据导入性能的n种方法

    详解PostgreSQL提升批量数据导入性能的n种方法

    这篇文章主要介绍了PostgreSQL提升批量数据导入性能的n种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • PostgreSQL定时清理旧数据的实现方法

    PostgreSQL定时清理旧数据的实现方法

    最近觉得数据库中每日数据不需要都保持,只需要保留30天的,所以这篇文章给大家介绍了PostgreSQL定时清理旧数据的实现方法,文中通过代码示例和图文给大家介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2024-03-03
  • postgresql中的ltree类型使用方法

    postgresql中的ltree类型使用方法

    这篇文章主要给大家介绍了关于postgresql中ltree类型使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用postgresql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • 用一整天的时间安装postgreSQL  NTFS权限

    用一整天的时间安装postgreSQL NTFS权限

    看标题貌似一天的收获不小,但实际上是被一个问题搞的要死,啥问题?额,又是NTFS权限的问题。
    2009-08-08
  • Windows 系统 PostgreSQL 手工安装配置方法

    Windows 系统 PostgreSQL 手工安装配置方法

    这篇文章主要介绍了Windows 系统 PostgreSQL 手工安装配置方法,本文主要说一下在 Windows 系统中安装 PostgreSQL 的方法,我这里没有采用 exe 安装包的形式去安装,EDB 发布的那个 exe 安装包形式的对于中文环境数据库的排序规则设定有问题,需要的朋友可以参考下
    2022-09-09
  • 详解如何优化在PostgreSQL中对于日期范围的查询

    详解如何优化在PostgreSQL中对于日期范围的查询

    在 PostgreSQL 中,处理日期范围的查询是常见的操作,然而,如果不进行适当的优化,这些查询可能会导致性能问题,特别是在处理大型数据集时,本文章将详细讨论如何优化在 PostgreSQL 中对于日期范围的查询,需要的朋友可以参考下
    2024-07-07
  • PGSQL实现判断一个空值字段,并将NULL值修改为其它值

    PGSQL实现判断一个空值字段,并将NULL值修改为其它值

    这篇文章主要介绍了PGSQL实现判断一个空值字段,并将NULL值修改为其它值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • postgresql连续归档及时间点恢复的操作

    postgresql连续归档及时间点恢复的操作

    这篇文章主要介绍了postgresql连续归档及时间点恢复的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL批量修改函数拥有者的操作

    PostgreSQL批量修改函数拥有者的操作

    这篇文章主要介绍了PostgreSQL批量修改函数拥有者的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL数据库实现公网远程连接的操作步骤

    PostgreSQL数据库实现公网远程连接的操作步骤

    PostgreSQL是一个功能非常强大的关系型数据库管理系统(RDBMS),本文呢将简单几步通过cpolar 内网穿透工具即可现实本地postgreSQL 远程访问,需要的朋友可以参考下
    2023-09-09

最新评论