2016-03-02 77 views
3

我有一個簡單的查詢,以檢查jsonb對象內部關鍵的存在檢查是否存在的關鍵在PostgreSQL的V9.5內心深處jsonb對象+

SELECT data->$1 jdata FROM "my-scheme"."my-table" 

我碰到2個proplems與此查詢:

1)它工作正常,如果我通過'foo'作爲$1但失敗"'foo'""'foo'->'bar'"。所以我不知道如何達到深度鍵。我使用node-postgres

2)我只想檢查密鑰是否存在,而不是通過該密鑰獲取所有數據。

所以問題是:我如何檢查密鑰是否存在於jsonb對象內部而無需通過該密鑰獲取所有數據?

回答

1
{ 
    "a": { 
     "b": 5 
    } 
} 

是有效的json。

{ 
    'a': { 
     'b': 5 
    } 
} 

是無效的json。在指定json字符串時使用雙引號(圍繞鍵),而在將它們寫入postgres標識符時使用單引號。

總之:

SELECT distinct true AS found FROM table_name WHERE column_name -> 'foo' ? 'bar'; 

更多嵌套:

SELECT distinct true AS found FROM jtest WHERE js -> 'a' -> 'c' ? 'd'; 

將返回1分的記錄,如果鑰匙被發現,和0個記錄,如果沒有鑰匙被發現。如果你不想指定路徑,那麼我認爲最好的過程是編寫一個函數/存儲過程來遍歷所有的鍵。

您正在尋找的操作員是?

摘錄自:http://www.postgresql.org/docs/9.5/static/functions-json.html

? text Does the string exist as a top-level key within the JSON value? 
6

可以使用操作者#>提取在特定路徑(被指定爲鍵陣列)的元素。

您還可以通過?運算符檢查頂級是否存在密鑰,儘管似乎沒有任何接受路徑的變體。

因此,無論這些都將做到這一點:

SELECT '{"a":{"b":{"c":1}}}'::jsonb #> '{a,b}' ? 'c' 
SELECT '{"a":{"b":{"c":1}}}'::jsonb #> '{a,b,c}' IS NOT NULL 

第二種可能是多一點效率,因爲它避免了因爲你連鎖經營機構一起構建中間jsonb值。