Postgresql JSON對(duì)象和數(shù)組查詢(xún)功能實(shí)現(xiàn)
一. Postgresql 9.5以下版本
1.1 簡(jiǎn)單查詢(xún)(缺陷:數(shù)組必須指定下標(biāo),不推薦)
1.1.1 模糊查詢(xún)
SELECT * FROM "public"."tf_low_data_testUser" WHERE "address" #>> '{0,name}' like '%bb%'
address字段是JSONArray類(lèi)型,所以在路徑中,使用數(shù)字索引來(lái)訪問(wèn)數(shù)組元素,從 0 開(kāi)始計(jì)數(shù)。
1.1.2 等值匹配
SELECT * FROM "public"."tf_low_data_testUser" WHERE "address" #>> '{0,name}' = 'bbb'
如果字段是int
類(lèi)型,后面需要添加::int
1.1.3 時(shí)間搜索
SELECT * FROM "public"."tf_low_data_testUser" WHERE "address" #>> '{0,date}' BETWEEN '2023-08-13' AND '2023-08-17'
1.1.4 在列表
SELECT * FROM "public"."tf_low_data_testUser" WHERE "address" #>> '{0,name}' IN ('bbb','ccc')
1.1.5 包含
SELECT * FROM "public"."tf_low_data_testUser" WHERE "address" #> '{0,roles,0,roleUsers}' @> '["eee"]'
#>
:獲取在指定路徑的 JSON 對(duì)象,路徑不存在則返回空。返回類(lèi)型是json(b)
#>>
:獲取在指定路徑的 JSON 對(duì)象,路徑不存在則返回空。返回類(lèi)型是text
1.2 多層級(jí)JSONArray(推薦)
如果表中有一個(gè)字段posts
,數(shù)據(jù)結(jié)構(gòu)為
[{ "name": "aaa", "ports": [{ "port": 443, "nickname": "ggg", "date": "2023-08-29", "address": ["111", "222"] }, { "port": 80, "nickname": "fff", "date": "2022-08-29", "address": ["333", "444"] }] }, { "name": "bbb", "ports": [{ "port": 2443, "nickname": "hhh", "date": "2021-08-29", "address": ["999"] }, { "port": 280, "nickname": "jjj", "date": "2020-08-29", "address": ["111111"] }] }]
1.2.1 模糊查詢(xún)
查詢(xún)nickname like '%jj%'
可以看出有兩層JSONArray結(jié)構(gòu)
SELECT * FROM "public"."tf_low_data_testUser" WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements("ports") as arr1(obj1) CROSS JOIN jsonb_array_elements(obj1->'ports') as arr2(obj2) WHERE (obj2->>'nickname') like '%gg%' );
當(dāng)該層級(jí)類(lèi)型是數(shù)組就添加
CROSS JOIN jsonb_array_elements(obj1->'ports') as arr2(obj2)
1.2.2 模糊查詢(xún) NOT
SELECT * FROM "public"."tf_low_data_testUser" WHERE NOT EXISTS ( SELECT 1 FROM jsonb_array_elements("ports") as arr1(obj1) CROSS JOIN jsonb_array_elements(obj1->'ports') as arr2(obj2) WHERE (obj2->>'nickname') like '%gg%' );
查的是另外三條數(shù)據(jù)源
1.2.3 等值匹配
SELECT * FROM "public"."tf_low_data_testUser" WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements("ports") as arr1(obj1) CROSS JOIN jsonb_array_elements(obj1->'ports') as arr2(obj2) WHERE (obj2->>'port')::int = 80 );
如果是數(shù)字類(lèi)型后面需要轉(zhuǎn)換
::int
,因?yàn)?->>
操作符的返回類(lèi)型是text
1.2.4 等值匹配 NOT
SELECT * FROM "public"."tf_low_data_testUser" WHERE NOT EXISTS ( SELECT 1 FROM jsonb_array_elements("ports") as arr1(obj1) CROSS JOIN jsonb_array_elements(obj1->'ports') as arr2(obj2) WHERE (obj2->>'port')::int = 80 );
查的是另外三條數(shù)據(jù)源
1.2.5 時(shí)間搜索
SELECT * FROM "public"."tf_low_data_testUser" WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements("ports") as arr1(obj1) CROSS JOIN jsonb_array_elements(obj1->'ports') as arr2(obj2) WHERE (obj2->>'date') BETWEEN '2022-08-13' AND '2023-08-17' );
1.2.6 時(shí)間搜索 NOT
查的是另外三條數(shù)據(jù)源
1.2.7 在列表
SELECT * FROM "public"."tf_low_data_testUser" WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements("ports") as arr1(obj1) CROSS JOIN jsonb_array_elements(obj1->'ports') as arr2(obj2) WHERE (obj2->>'nickname') IN ('ggg','fff') );
1.2.8 在列表 NOT
查的是另外三條數(shù)據(jù)源
1.2.9 包含
SELECT * FROM "public"."tf_low_data_testUser" WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements("ports") as arr1(obj1) CROSS JOIN jsonb_array_elements(obj1->'ports') as arr2(obj2) WHERE (obj2->'address') @> '["444"]' );
此時(shí)使用的操作符是
->
,返回值是jsonb
類(lèi)型
1.2.10 包含 NOT
查的是另外三條數(shù)據(jù)源
二. Postgresql 9.5和以上版本
也兼容上面的JSON查詢(xún)
2.1 模糊查詢(xún)
使用函數(shù)
jsonb_path_exists
(可以指定JSON
路徑,如果是數(shù)組添加[*]
)的正則查詢(xún)達(dá)到模糊查詢(xún)的效果
-- like '%ggg%' SELECT * FROM "public"."tf_low_data_testUser" WHERE jsonb_path_exists("ports", '$[*].ports[*].nickname ?(@ like_regex "g")') -- 左模糊 like '%g' SELECT * FROM "public"."tf_low_data_testUser" WHERE jsonb_path_exists("ports", '$[*].ports[*].nickname ?(@ like_regex "g$")') -- 右模糊 like 'g%' SELECT * FROM "public"."tf_low_data_testUser" WHERE jsonb_path_exists("ports", '$[*].ports[*].nickname ?(@ like_regex "^g")') -- 等值匹配 SELECT * FROM "public"."tf_low_data_testUser" WHERE jsonb_path_exists("ports", '$[*].ports[*].nickname ?(@ like_regex "^ggg$")')
同樣支持
NOT
2.2 等值匹配
SELECT * FROM "public"."tf_low_data_testUser" WHERE jsonb_path_exists("ports", '$[*].ports[*].nickname ?(@ == "fff")')
同樣支持
NOT
2.3 時(shí)間搜索
SELECT * FROM "public"."tf_low_data_testUser" WHERE jsonb_path_exists("ports", '$[*].ports[*].date ?(@ >= "2022-01-02" && @ <= "2023-08-02")')
同樣支持
NOT
2.4 在列表
SELECT * FROM "public"."tf_low_data_testUser" WHERE jsonb_path_exists("ports", '$[*].ports[*].nickname ?(@ == "ggg" || @ == "fff")')
同樣支持
NOT
2.5 包含
和
等值匹配
一樣
SELECT * FROM "public"."tf_low_data_testUser" WHERE jsonb_path_exists("ports", '$[*].ports[*].address ?(@ == "222")')
同樣支持
NOT
到此這篇關(guān)于Postgresql JSON對(duì)象和數(shù)組查詢(xún)的文章就介紹到這了,更多相關(guān)Postgresql JSON對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PostgreSQL中offset...limit分頁(yè)優(yōu)化的一些常見(jiàn)手段
我們?cè)谑褂脭?shù)據(jù)庫(kù)進(jìn)行分頁(yè)查詢(xún)時(shí),隨著offset過(guò)濾的數(shù)據(jù)越來(lái)越多,查詢(xún)也會(huì)越來(lái)越慢,下面這篇文章主要給大家介紹了關(guān)于PostgreSQL中offset...limit分頁(yè)優(yōu)化的一些常見(jiàn)手段,需要的朋友可以參考下2023-05-05PostgreSQL 實(shí)現(xiàn)登錄及修改密碼操作
這篇文章主要介紹了PostgreSQL 實(shí)現(xiàn)登錄及修改密碼操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01使用python-slim鏡像遇到無(wú)法使用PostgreSQL的問(wèn)題及解決方法
這篇文章主要介紹了使用python-slim鏡像遇到無(wú)法使用PostgreSQL的問(wèn)題及解決方法,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08PostgreSQL中查看當(dāng)前時(shí)間和日期的幾種常用方法
在 PostgreSQL 中,有多個(gè)函數(shù)可以用來(lái)查看當(dāng)前時(shí)間和日期,這些函數(shù)在處理時(shí)間戳、日期和時(shí)間的計(jì)算時(shí)非常有用,以下是幾種常用的查看當(dāng)前時(shí)間和日期的函數(shù)及示例,需要的朋友可以參考下2024-10-10關(guān)于PostgreSQL 行排序的實(shí)例解析
這篇文章主要介紹了關(guān)于PostgreSQL 行排序的實(shí)例解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01PostgreSQL LIST、RANGE 表分區(qū)的實(shí)現(xiàn)方案
這篇文章主要介紹了PostgreSQL LIST、RANGE 表分區(qū)的實(shí)現(xiàn)方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01解決postgresql 數(shù)字轉(zhuǎn)換成字符串前面會(huì)多出一個(gè)空格的問(wèn)題
這篇文章主要介紹了解決postgresql 數(shù)字轉(zhuǎn)換成字符串前面會(huì)多出一個(gè)空格的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12PgSQL條件語(yǔ)句與循環(huán)語(yǔ)句示例代碼詳解
這篇文章主要介紹了PgSQL條件語(yǔ)句與循環(huán)語(yǔ)句,pgSQL中有兩種條件語(yǔ)句分別為if與case語(yǔ)句,每種語(yǔ)句通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07PostgreSql生產(chǎn)級(jí)別數(shù)據(jù)庫(kù)安裝要注意事項(xiàng)
這篇文章主要介紹了PostgreSql生產(chǎn)級(jí)別數(shù)據(jù)庫(kù)安裝要注意事項(xiàng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08