W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
本節(jié)描述:
用于處理和創(chuàng)建JSON數(shù)據(jù)的函數(shù)和運(yùn)算器
SQL/JSON路徑語言
要了解有關(guān)SQL/JSON標(biāo)準(zhǔn)的更多信息,請參閱[sqltr-19075-6]。有關(guān)PostgreSQL中支持的JSON類型的詳細(xì)信息,見 第 8.14 節(jié)。 .
表 9.44展示了可以用于 JSON 數(shù)據(jù)類型(見第 8.14 節(jié))的操作符。 此外,表 9.1所示的常用比較操作符也適用于jsonb
,但不適用于json
。 比較操作符遵循 第 8.14.4 節(jié)中的B樹操作概要的排序規(guī)則。
表 9.44. json
和 jsonb
操作符
操作符 描述 例子 |
---|
提取JSON數(shù)組的第 |
用給定的鍵提取JSON對象字段。 |
提取JSON數(shù)組的第 |
用給定的鍵提取JSON對象字段,作為 |
提取指定路徑下的JSON子對象,路徑元素可以是字段鍵或數(shù)組索引。 |
將指定路徑上的JSON子對象提取為 |
如果JSON輸入沒有匹配請求的正確結(jié)構(gòu),字段/元素/路徑提取操作符返回NULL,而不是失敗;例如,如果不存在這樣的鍵或數(shù)組元素。
還有一些操作符僅適用于jsonb
,如表表 9.45所示。 第第 8.14.4 節(jié)描述了如何使用這些操作符來有效地搜索索引的
jsonb
數(shù)據(jù)。
表 9.45. 附加的 jsonb
操作符
操作符 描述 例子 |
---|
第一個JSON值是否包含第二個?(請參見第 8.14.3 節(jié)以了解包含的詳細(xì)信息。) |
第二個JSON中是否包含第一個JSON值? |
文本字符串是否作為JSON值中的頂級鍵或數(shù)組元素存在? |
文本數(shù)組中的字符串是否作為頂級鍵或數(shù)組元素存在? |
文本數(shù)組中的所有字符串都作為頂級鍵或數(shù)組元素存在嗎? |
連接兩個 |
從JSON對象中刪除鍵(以及它的值),或從JSON數(shù)組中刪除匹配的字符串值。 |
從左操作數(shù)中刪除所有匹配的鍵或數(shù)組元素。 |
刪除具有指定索引的數(shù)組元素(負(fù)整數(shù)從末尾計數(shù))。如果JSON值不是數(shù)組,則拋出錯誤。 |
刪除指定路徑上的字段或數(shù)組元素,路徑元素可以是字段鍵或數(shù)組索引。 |
JSON路徑是否為指定的JSON值返回任何項? |
返回指定JSON值的JSON路徑謂詞檢查的結(jié)果。只考慮結(jié)果的第一項。如果結(jié)果不是布爾值,則返回 |
jsonpath
操作符@?
和 @@
抑制以下錯誤:缺少對象字段或數(shù)組元素,意外的JSON項目類型,日期時間和數(shù)字錯誤。 還可以告訴以下描述的與jsonpath
相關(guān)的函數(shù)來抑制這些類型的錯誤。在搜索不同結(jié)構(gòu)的JSON文檔集合時,此行為可能會有所幫助。 The jsonpath
operators
@?
and @@
suppress the following errors: missing object field or array element, unexpected JSON item type, datetime and numeric errors. The jsonpath
-related functions described below can also
be told to suppress these types of errors. This behavior might be helpful when searching JSON document collections of varying structure.
表 9.46 顯示可用于構(gòu)造json
和jsonb
值的函數(shù)。
表 9.46. JSON 創(chuàng)建函數(shù)
函數(shù) 描述 例子 |
---|
將任何SQL值轉(zhuǎn)換為 |
將SQL數(shù)組轉(zhuǎn)換為JSON數(shù)組。該行為與 |
將SQL組合值轉(zhuǎn)換為JSON對象。該行為與 |
根據(jù)可變參數(shù)列表構(gòu)建可能異構(gòu)類型的JSON數(shù)組。每個參數(shù)都按照 |
根據(jù)可變參數(shù)列表構(gòu)建一個JSON對象。按照慣例,參數(shù)列表由交替的鍵和值組成。 關(guān)鍵參數(shù)強(qiáng)制轉(zhuǎn)換為文本;值參數(shù)按照 |
從文本數(shù)組構(gòu)建JSON對象。該數(shù)組必須有兩個維度,一個維度的成員數(shù)為偶數(shù),在這種情況下,它們被視為交替的鍵/值對; 另一個維度的成員數(shù)為二維,每個內(nèi)部數(shù)組恰好有兩個元素,它們被視為鍵/值對。所有值都轉(zhuǎn)換為JSON字符串。
|
這種形式的 |
[a]
例如,hstore擴(kuò)展有一個從 |
表 9.47 顯示可用于處理json
和jsonb
值的函數(shù)。
表 9.47. JSON 處理函數(shù)
函數(shù) 描述 例子 |
---|
將頂級JSON數(shù)組展開為一組JSON值。
|
將頂級JSON數(shù)組展開為一組
|
返回頂級JSON數(shù)組中的元素數(shù)量。 |
將頂級JSON對象展開為一組鍵/值對。
|
將頂級JSON對象擴(kuò)展為一組鍵/值對。返回的
|
在指定路徑下提取JSON子對象。(這在功能上相當(dāng)于 |
將指定路徑上的JSON子對象提取為 |
返回頂級JSON對象中的鍵集合。
|
將頂級JSON對象擴(kuò)展為具有 要將JSON值轉(zhuǎn)換為輸出列的SQL類型,需要按次序應(yīng)用以下規(guī)則:
雖然下面的示例使用一個常量JSON值,典型的用法是在查詢的
|
將對象的頂級JSON數(shù)組展開為一組具有
|
將頂級JSON對象展開為具有由
|
將頂級JSON對象數(shù)組展開為一組由
|
返回 |
如果 |
返回插入 |
從給定的JSON值中刪除所有具有空值的對象字段,遞歸地。非對象字段的空值是未受影響的。 |
檢查JSON路徑是否返回指定JSON值的任何項。如果指定了 |
返回指定JSON值的JSON路徑謂詞檢查的結(jié)果。只有結(jié)果的第一項被考慮在內(nèi)。 如果結(jié)果不是布爾值,則返回 |
為指定的JSON值返回由JSON路徑返回的所有JSON項??蛇x的
|
以JSON數(shù)組的形式返回由JSON路徑為指定的JSON值返回的所有JSON項??蛇x的 |
為指定的JSON值返回由JSON路徑返回的第一個JSON項。如果沒有結(jié)果則返回 |
這些函數(shù)與上面描述的沒有 |
將給定的JSON值轉(zhuǎn)換為精美打印的,縮進(jìn)的文本。
|
以文本字符串形式返回頂級JSON值的類型??赡艿念愋陀?code class="literal">object, |
參見 第 9.21 節(jié),聚合函數(shù)json_agg
將聚合記錄值為JSON,聚合函數(shù)json_object_agg
將聚合成對的值為JSON對象, 以及它們在jsonb
中的相當(dāng)?shù)?函數(shù)),
jsonb_agg
和jsonb_object_agg
。
SQL/JSON路徑表達(dá)式指定了要從JSON數(shù)據(jù)中檢索的項目,類似于SQL訪問XML時使用的XPath表達(dá)式。 在PostgreSQL中,路徑表達(dá)式作為jsonpath
數(shù)據(jù)類型實現(xiàn),可以使用第 8.14.6 節(jié)中描述的任何元素。
JSON查詢函數(shù)和操作符將提供的路徑表達(dá)式傳遞給path engine進(jìn)行評估。 如果表達(dá)式與被查詢的JSON數(shù)據(jù)匹配,則返回相應(yīng)的JSON項或項集。 路徑表達(dá)式是用SQL/JSON路徑語言編寫的,也可以包括算術(shù)表達(dá)式和函數(shù)。
路徑表達(dá)式由jsonpath
數(shù)據(jù)類型允許的元素序列組成。路徑表達(dá)式通常從左向右求值,但你可以使用圓括號來更改操作的順序。 如果計算成功,將生成一系列JSON項,并將計算結(jié)果返回到JSON查詢函數(shù),該函數(shù)將完成指定的計算。
要引用正在查詢的JSON值(context item項),在路徑表達(dá)式中使用$
變量。 它后面可以跟著一個或多個accessor operators,這些操作符在JSON結(jié)構(gòu)中逐級向下檢索上下文項的子項。
后面的每個操作符處理前一個求值步驟的結(jié)果。
例如,假設(shè)你有一些你想要解析的來自GPS跟蹤器的JSON數(shù)據(jù),例如:
{
"track": {
"segments": [
{
"location": [ 47.763, 13.4034 ],
"start time": "2018-10-14 10:05:14",
"HR": 73
},
{
"location": [ 47.706, 13.2635 ],
"start time": "2018-10-14 10:39:21",
"HR": 135
}
]
}
}
為了檢索可用的軌跡段,你需要使用.
訪問操作符來向下瀏覽周邊的JSON對象:key
$.track.segments
要檢索數(shù)組的內(nèi)容,通常使用[*]
操作符。例如,下面的路徑將返回所有可用軌道段的位置坐標(biāo):
$.track.segments[*].location
要只返回第一個段的坐標(biāo),可以在[]
訪問操作符中指定相應(yīng)的下標(biāo)。重新調(diào)用相對于0的JSON數(shù)組索引:
$.track.segments[0].location
每個路徑求值步驟的結(jié)果可以由本文中第 9.16.2.2 節(jié)中列出的一個或多個jsonpath
操作符和方法來處理。 每個方法名之前必須有一個點。例如,你可以得到一個數(shù)組的大小:
$.track.segments.size()
在路徑表達(dá)式中使用jsonpath
操作符和方法的更多示例見下面本文中第 9.16.2.2 節(jié)。
在定義路徑時,還可以使用一個或多個與SQL中的WHERE
子句類似的filter expressions。 過濾器表達(dá)式以問號開頭,并在圓括號中提供條件:
? (condition
)
過濾表達(dá)式必須在它們應(yīng)該應(yīng)用的路徑求值步驟之后寫入。該步驟的結(jié)果將被篩選,以只包括滿足所提供條件的那些項。 SQL/JSON定義了三值邏輯,因此條件可以是 true
, false
,或 unknown
。 unknown
值發(fā)揮與SQL NULL
相同的角色,可以使用
is unknown
謂詞進(jìn)行測試。 進(jìn)一步的路徑求值步驟只使用篩選器表達(dá)式返回true
的那些項。
可以在過濾表達(dá)式中使用的函數(shù)和操作符羅列在表 9.49中。 在一個過濾表達(dá)式中,@
變量表示被過濾的值(也就是說,前面路徑步驟的一個結(jié)果)。你可以在 @
后面寫訪問操作符來檢索組件項。
例如,假設(shè)你想要檢索所有高于130的心率值。你可以使用下面的表達(dá)式來實現(xiàn)這一點:
$.track.segments[*].HR ? (@ > 130)
為了獲得具有這些值的片段的開始時間,必須在返回開始時間之前過濾掉不相關(guān)的片段,所以過濾表達(dá)式應(yīng)用于上一步,條件中使用的路徑不同:
$.track.segments[*] ? (@.HR > 130)."start time"
如果需要,可以按順序使用幾個過濾器表達(dá)式。例如,下面的表達(dá)式選擇所有包含有相關(guān)坐標(biāo)和高心率值的位置的段的開始時間:
$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"
也允許在不同嵌套層級中使用過濾器表達(dá)式。下面的例子首先根據(jù)位置篩選所有的片段,然后返回這些片段的高心率值,如果適用的話:
$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)
你也可以在彼此之間嵌套過濾器表達(dá)式:
$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()
如果包含任何具有高心率值的片段,則該表達(dá)式返回曲目的大小,否則返回空序列。
PostgreSQL的SQL/JSON路徑語言的實現(xiàn)與SQL/JSON標(biāo)準(zhǔn)有以下偏差:
路徑表達(dá)式可以是布爾謂詞,盡管SQL/JSON標(biāo)準(zhǔn)只允許在過濾器中使用謂詞。 這是實現(xiàn)@@
操作符所必需的。例如,下面的jsonpath
表達(dá)式在PostgreSQL中是有效的:
$.track.segments[*].HR < 70
在解釋like_regex
過濾器中使用的正則表達(dá)式模式方面有一些小的差異,如本文中第 9.16.2.3 節(jié)中所述。
當(dāng)查詢JSON數(shù)據(jù)時,路徑表達(dá)式可能與實際的JSON數(shù)據(jù)結(jié)構(gòu)不匹配。 試圖訪問不存在的對象成員或數(shù)組元素會導(dǎo)致結(jié)構(gòu)錯誤。SQL/JSON路徑表達(dá)式有兩種處理結(jié)構(gòu)錯誤的模式:
不嚴(yán)格的(lax)(默認(rèn))—路徑引擎隱式地將查詢的數(shù)據(jù)適配到指定的路徑。任何剩余的結(jié)構(gòu)錯誤都將被抑制并轉(zhuǎn)換為空SQL/JSON序列。
嚴(yán)格的(strict) —如果發(fā)生了結(jié)構(gòu)錯誤,則會引發(fā)錯誤。
如果JSON數(shù)據(jù)不符合期望的模式,不嚴(yán)格的(lax)模式有助于匹配JSON文檔結(jié)構(gòu)和路徑表達(dá)式。 如果操作不匹配特定操作的要求,可以自動將其包裝為SQL/JSON數(shù)組,也可以在執(zhí)行該操作之前將其元素轉(zhuǎn)換為SQL/JSON序列來解包裝。 此外,比較操作符會自動以lax模式打開它們的操作數(shù),因此你可以開包即用的就能比較SQL/JSON數(shù)組。 大小為1的數(shù)組被認(rèn)為等于它的唯一元素。只有在以下情況下才不會自動展開:
路徑表達(dá)式包含type()
或size()
方法,它們分別返回數(shù)組中的元素類型和數(shù)量。
查詢的JSON數(shù)據(jù)包含嵌套的數(shù)組。在本例中,只有最外層的數(shù)組被打開,而所有內(nèi)部數(shù)組保持不變。 因此,隱式展開在每個路徑求值步驟中只能向下進(jìn)行一級。
例如,當(dāng)查詢上面列出的GPS數(shù)據(jù)時,當(dāng)使用不嚴(yán)格的(lax)模式時,你可以從它存儲了一組片段的事實中抽象出來:
lax $.track.segments.location
在嚴(yán)格的(strict)模式中,指定的路徑必須與查詢的JSON文檔的結(jié)構(gòu)完全匹配才能返回SQL/JSON項,因此使用該路徑表達(dá)式會導(dǎo)致錯誤。 要得到與不嚴(yán)格的(lax)模式相同的結(jié)果,你必須顯式地打開segments
數(shù)組:
strict $.track.segments[*].location
表 9.48顯示了jsonpath中可用的操作符和方法。 請注意,雖然一元操作符和方法可以應(yīng)用于由前一個路徑步驟產(chǎn)生的多個值,二元操作符(加法等)只能應(yīng)用于單個值。
表 9.48. jsonpath
操作符和方法
操作符/方法 描述 例子 |
---|
加法 |
一元加號(無操作);與加法不同,這個可以迭代多個值 |
減法 |
否定;與減法不同,它可以迭代多個值 |
乘法 |
除法 |
模數(shù) (余數(shù)) |
JSON項的類型 (參見 |
JSON項的大小(數(shù)組元素的數(shù)量,如果不是數(shù)組則為1) |
從JSON數(shù)字或字符串轉(zhuǎn)換過來的近似浮點數(shù) |
大于或等于給定數(shù)字的最接近的整數(shù) |
小于或等于給定數(shù)字的最近整數(shù) |
給定數(shù)字的絕對值 |
從字符串轉(zhuǎn)換過來的日期/時間值 |
使用指定的 |
對象的鍵值對,表示為包含三個字段的對象數(shù)組: |
datetime()
和datetime(
方法的結(jié)果類型可以是template
)date
, timetz
, time
,timestamptz
, 或 timestamp
。 這兩個方法都動態(tài)地確定它們的結(jié)果類型。
datetime()
方法依次嘗試將其輸入字符串與date
, timetz
, time
,timestamptz
, 和 timestamp
的ISO格式進(jìn)行匹配。 它在第一個匹配格式時停止,并發(fā)出相應(yīng)的數(shù)據(jù)類型。
datetime(
方法根據(jù)所提供的模板字符串中使用的字段確定結(jié)果類型。template
)
datetime()
和datetime(
方法使用與template
)to_timestamp
SQL函數(shù)相同的解析規(guī)則(see 第 9.8 節(jié)),但有三個例外。 首先,這些方法不允許不匹配的模板模式。 其次,模板字符串中只允許以下分隔符:減號、句點、solidus(斜杠)、逗號、撇號、分號、冒號和空格。
第三,模板字符串中的分隔符必須與輸入字符串完全匹配。
如果需要比較不同的日期/時間類型,則應(yīng)用隱式轉(zhuǎn)換。 date
值可以轉(zhuǎn)換為timestamp
或 timestamptz
, timestamp
可以轉(zhuǎn)換為timestamptz
, time
可以轉(zhuǎn)換為
timetz
。 但是,除了第一個轉(zhuǎn)換外,其他所有轉(zhuǎn)換都依賴于當(dāng)前TimeZone設(shè)置,因此只能在時區(qū)感知的jsonpath
函數(shù)中執(zhí)行。
表 9.49顯示了適用的過濾器表達(dá)式元素。
表 9.49. jsonpath
過濾器表達(dá)式元素
謂詞/值 描述 例子 |
---|
相等比較(這個,和其他比較操作符,適用于所有JSON標(biāo)量值) |
不相等比較 |
小于比較 |
小于或等于比較 |
大于比較 |
大于或等于比較 |
JSON常數(shù) |
JSON常數(shù) |
JSON常數(shù) |
布爾 AND |
布爾 OR |
布爾 NOT |
測試布爾條件是否為 |
測試第一個操作數(shù)是否與第二個操作數(shù)給出的正則表達(dá)式匹配,可選使用由一串 |
測試第二個操作數(shù)是否為第一個操作數(shù)的初始子串。 |
測試路徑表達(dá)式是否至少匹配一個SQL/JSON項。 如果路徑表達(dá)式會導(dǎo)致錯誤,則返回 |
SQL/JSON路徑表達(dá)式允許通過like_regex
過濾器將文本匹配為正則表達(dá)式。 例如,下面的SQL/JSON路徑查詢將不區(qū)分大小寫地匹配以英語元音開頭的數(shù)組中的所有字符串:
$[*] ? (@ like_regex "^[aeiou]" flag "i")
可選的flag
字符串可以包括一個或多個字符i
用于不區(qū)分大小寫的匹配,m
允許^
和$
在換行時匹配,s
允許.
匹配換行符,
q
引用整個模式(將行為簡化為一個簡單的子字符串匹配)。
SQL/JSON標(biāo)準(zhǔn)借用了來自LIKE_REGEX
操作符的正則表達(dá)式定義,其使用了XQuery標(biāo)準(zhǔn)。 PostgreSQL目前不支持LIKE_REGEX
操作符。因此,like_regex
過濾器是使用第 9.7.3 節(jié)中描述的POSIX正則表達(dá)式引擎來實現(xiàn)的。 這導(dǎo)致了與標(biāo)準(zhǔn)SQL/JSON行為的各種細(xì)微差異,這在第 9.7.3.8 節(jié)中進(jìn)行了分類。 但是請注意,這里描述的標(biāo)志字母不兼容并不適用于SQL/JSON,因為它將XQuery標(biāo)志字母翻譯為符合POSIX引擎的預(yù)期。
請記住,like_regex
的模式參數(shù)是一個JSON路徑字符串文字,根據(jù)第 8.14.6 節(jié)給出的規(guī)則編寫。 這特別意味著在正則表達(dá)式中要使用的任何反斜杠都必須加倍。例如,匹配只包含數(shù)字的字符串:
$ ? (@ like_regex "^\\d+$")
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: