关于pgsql 的json 和jsonb 的数据处理笔记

1. json 和jsonb 区别
两者从用户操作的角度来说没有区别,区别主要是存储和读取的系统处理(预处理)和耗时方面有区别。json写入快,读取慢,jsonb写入慢,读取快。

2. 常用的操作符

操作符:

-> // 右边传入整数(针对纯数组),获取数组的第n个元素,n从0开始算,返回值为json

示例: select '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2 // 输出 {"c":"baz"}

-> // 右边传入键值(针对关联数组),获取数组的第n个元素,n从0开始算,返回值为json

示例: select '{"a": {"b":"foo"}, "c":{"a": "aaa"}}'::json->'a' // 输出 {"b":"foo"}

->> // 右边传入整数(针对纯数组),获取数组的第n个元素,n从0开始算,返回值为文本

示例: select '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->>2 // 输出 {"c":"baz"}

->> // 右边传入键值(针对关联数组),获取数组的第n个元素,n从0开始算,返回值为文本

示例: select '{"a": {"b":"foo"}, "c":{"a": "aaa"}}'::json->>'a' // 输出 {"b":"foo"}

#> // 获取json子对象,传入数组,返回json

示例: select '{"a": {"b":{"c": "foo"}}}'::json#> '{a,b}' // 输出 {"c": "foo"}

#>> // 获取json子对象并转换为文本,传入数组,返回文本

示例: select '{"a": {"b":{"c": "foo"}}}'::json#>> '{a,b}' // 输出 {"c": "foo"}

3. 操作函数
目前pgsql版本提供了两套函数分别处理,可以通用,名称也差不多,比如 json_each 和 jsonb_each , json_array_elements 和 jsonb_array_elements 。

json相关的处理函数比较多,常用的有如下三个,这三个基本够用了

json_object_keys  // 返回json的键(多层只返回第一层),该函数不能用于纯数组.

json_array_elements  // 提取转换纯数组元素

json_extract_path   // 返回JSON值所指向的某个键元素(相当于 #> 操作符),该函数不能直接操作纯数组。

需要注意的是如果你创建字段用的是json就用json相关函数,如果创建字段用的是jsonb就用jsonb相关函数。

json_object_keys 函数示例:

select json_object_keys ('
{
"goods":
[
{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"}
],
"quantity": "10"
}
')

输出:

json_object_keys 函数示例:

select json_object_keys ('

{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"}
], 
')

输出:

ERROR:  cannot call json_object_keys on an array     // 不能用于数组

json_array_elements  函数 示例:

select json_array_elements ('
[
{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"},
{"id": "111a13d3-0225-4431-b858-678c3cfea999", "weight": "3", "quantity": "11"}
]
')

我们看到json数据被分离成三条记录,这时我们就可以对其进行查询操作,

比如查询是否包含了weight=3的数据。

select * from json_array_elements ('
[
{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"},
{"id": "111a13d3-0225-4431-b858-678c3cfea999", "weight": "3", "quantity": "11"}
]
') as jae
where jae::jsonb->>'weight' = '3'

#输出:

我们看到这样就可以到对json数据内部进行查询了。

json_extract_path   函数示例:

比如要获取键 ‘goods’ 的值:

{
"goods":

{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"}
], 
"quantity": {"max": "150", "min": "2"}
}

select json_extract_path   ('
{
"goods":

{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"}
], 
"quantity": {"max": "150", "min": "2"}
}
' , 'goods' )  ;   // 第二个参数表示获取键为goods的值

#输出:

json_extract_path   函数和  pgsql  提供的操作符  #>  是一样的。

select ('
{
"goods":
[
{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"}
],
"quantity": {"max": "150", "min": "2"}
}
') ::json #> '{goods}'

两者的输出是一致的。

同样我们要输出 键quantity 下键max 的值:

select json_extract_path   ('
{
"goods":

{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"}
], 
"quantity": {"max": "150", "min": "2"}
}
' , 'quantity','max' ) ;

-- 或

select ('
{
"goods":

{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"}
], 
"quantity": {"max": "150", "min": "2"}
}
') ::json #> '{quantity, max}'

两者输出是一样的。

这几个函数是可以联合使用的。

比如我们要查询 键“goods” 下weight =2 的id 和quantity 值,语句如下:

select jae::json->>'id' as id, jae::json->>'quantity' as quantity from json_array_elements (
json_extract_path ('
{
"goods":
[
{"id": "676a13d3-0225-4431-b858-678c3cfeab74", "weight": "1", "quantity": "9999999"},
{"id": "111a13d3-0225-4431-b858-678c3cfeab75", "weight": "2", "quantity": "33"}
],
"quantity": {"max": "150", "min": "2"}
}
' , 'goods' ) ) as jae where jae::json->> 'weight' = '2'

#输出:

上述的json语句我们可以当做字段来使用,就相当于对表记录进行操作了。

接下来我们同个一个例子讲解json在表中的用法:

示例:查询表中jsonb_msg字段中goods下id=1003和1002的记录,表中输入如下图:

sql查询语句:

select name,* from upgrade_test.test1 test
where
( select count(*) from jsonb_array_elements (
jsonb_extract_path(test.json_msg , 'goods' ) ) as jae where jae::json->> 'id' in ('1001','1003') ) > 0 ;

#输出:

效率还行:

Total query runtime: 11 msec
检索到 2 行。

官方文档页:

https://www.postgresql.org/docs/9.4/static/functions-json.html

关于pgsql 的json 和jsonb 的数据查询操作笔记整理的更多相关文章

  1. Android+Servlet+MySql+JSON实现简单的数据查询操作--C/S架构

    本例简单地实现Android客户端与服务器端交互,主要是通过客户端输入内容(学号)提交到服务器端,服务器端与数据库交互去查询相应信息(姓名).根据这个做个完整的安卓登录是没问题的.本例数据库服务器都采 ...

  2. MongoDB源码分析——mongod数据查询操作

    源码版本为MongoDB 2.6分支 Edit mongod数据查询操作 在mongod的初始化过程中说过,服务端接收到客户端消息后调用MyMessageHandler::process函数处理消息. ...

  3. mongo数据查询操作

    本文来源于 :Stephen Liu 1.  基本查询:     构造查询数据.    > db.test.findOne()    {         "_id" : Ob ...

  4. mongodb数据库添加权限及简单数据库命令操作笔记

    加固mongodb建议:修改数据库默认端口,添加数据库访问权限: 启动数据库(裸奔):C:\mongodb\bin>mongod --dbpath C:\MongoDB\data(同时用--db ...

  5. sql数据查询基础笔记

    使用SELETE语句进行查询 语法 SELECT<列名> FROM<表名>  [ORDER BY <排序的列名>[ASC或DESC]] 1.查询所有的数据和列 SE ...

  6. Oracle数据 查询操作日志

    SELECT t.SQL_TEXT, t.FIRST_LOAD_TIME,t.PARSING_SCHEMA_NAME FROM v$sqlarea t WHERE t.SQL_TEXT LIKE 'D ...

  7. htm5-websocket实现数据查询应用

    htm5-websocket实现数据查询应用   在之前的文章讲述了使用Websocket调用远程方式的功能,在这基础我们可以简单地使用WebSocket进行数据处理方面的应用;只需要在方法执行相关的 ...

  8. Laravel Eloquent 数据查询结果中日期的格式化

    两种情况: 使用 Model 的查询 例如: $item = App\Models\Apple::first(); $date = $item->created_at->format('Y ...

  9. 关于QueryRunner数据查询以及常用方法

    QueryRunner数据查询操作调用QueryRunner类方法query(Connection con,String sql,ResultSetHandler r, Object.params)R ...

随机推荐

  1. jdk8-》stream⾥的map和filter函数使⽤

    map函数 将流中的每⼀个元素 T(入参) 映射为 R(返回值)(类似类型转换)    类似遍历集合,对集合的每个对象做处理.场景:转换对象,如javaweb开发中集合⾥⾯的DO对象转换为DTO对象 ...

  2. VS 2017 mscorlib.dll 加载元数据时发生严重错误,需要终止调试

    VS 2017 mscorlib.dll 加载元数据时发生严重错误,需要终止调试 C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0. ...

  3. 通过css修改input的边框

    input{ border:1px solid #d2d2d2; background-color:transparent; } 可以看到主要是把背景色调成透明的颜色,从而来进行边框的设置

  4. Centos7在防火墙中添加访问端口

    1.       查看jenkins启动状态命令:systemctl status Jenkins 保证jenkins启动,此处的状态为正在运行 2.       查看防火墙状态命令:systemct ...

  5. IntelliJ IDEA常规配置教程

      IntelliJ IDEA,是java编程语言开发的集成环境.IntelliJ在业界被公认为最好的java开发工具,尤其在智能代码助手.代码自动提示.重构.J2EE支持.各类版本工具(git.sv ...

  6. thinkphp中路由的基本使用

    1.在application中下的config.php中 以下代码改为true // 是否开启路由 'url_route_on' => true, // 是否强制使用路由 'url_route_ ...

  7. Django REST framework快速入门(官方文档翻译翻译)

    开始 我们将创建一个简单的API来允许管理员用户查看和编辑系统中的用户和组. 项目设置 创建一个新的django项目,命名为:<tutorial>,然后创建一个新的应用程序(app),命名 ...

  8. 解决ERROR 1130: Host 'x.x.x.x' is not allowed to connect to this MariaDB server 方法

    问题描述 在使用SQLyog操作Linux上的MariaDB时候,会出现如下错误: 解决方法 改表法 可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电 ...

  9. 实现排行榜神器——redis zset

    需求:假如现在需要搞个 “运动消耗卡路里排行榜”,例似微信步数排名,显示排名前20人的信息和消耗的卡里路,怎样实现排序? 一般思路:存储信息,然后数据库查询,排序?(假如有几十万人参与排名,这样查my ...

  10. SpringBean的生命周期以及循环依赖过程

    上面就是springBean的大致生命周期. Bean的创建过程 创建Bean之前会调用Bean工厂的后置处理器,可以获取到BeanDefinition Bean的初始化过程 初始化之前会调用前置处理 ...