關於pgsql 的json 和jsonb 的數據查詢操作筆記整理


關於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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM