測試環境為 CentOS 8 x86_64
path : ['lax'] '$' [step]*
lax : MariaDB 只支援這個模式,如果路徑運算式找不到,則傳回 NULL,下面我們來看一下後面 ‘$’ [step]* 使用方式.
讀取 JSON 資料主要可以區分為 值 (Value) , 物件 (Object) , 陣列 (Array),可以透過以下三個函數.
- 如果回傳值為 值 (Value) 時使用 JSON_VALUE.
- 但如是 物件 (Object) ,或是 陣列 (Array) 需使用 JSON_QUERY.
- 或是使用 JSON_EXTRACT.
更多關於 JSON_QUERY , JSON_VALUE 以及 JSON_EXTRACT 函數請參考 – https://benjr.tw/103237
關於 JSONPath Expressions 說明 – https://mariadb.com/kb/en/jsonpath-expressions/
Object Member Selector
To select member(s) in a JSON object, one can use one of the following:
- .memberName – 名稱中沒有 有效標識符 (valid identifier) 直接指定名稱即可.
- .”memberName” – 名稱包含有效標識符 (valid identifier – space, dot, and/or other characters) 時需使用雙引號 ” (Double Quotes) 來指定.
- .* – selects the values of all members of the object.
If the current item is an array (instead of an object), nothing will be selected.
下面是一個 JSON 格式(物件)的範例.
[php] MariaDB [(none)]> SET @JOBJECT='{ "Main Board": "ASUS", "CPU": { "CPU 1": "Intel", "CPU 2": "Intel" }, "MEM": { "MEM 1": "Hynix", "MEM 2": "Hynix", "MEM 3": "Samsung", "MEM 4": "Samsung" } }'; Query OK, 0 rows affected (0.000 sec)
去讀取 Main Board 的值 (讀值時使用 JSON_VALUE 函數).
MariaDB [(none)]> SELECT JSON_VALUE(@JOBJECT,'$.Main Board'); +------------------------------------+ | JSON_VALUE(@JVALUE,'$.Main Board') | +------------------------------------+ | ASUS | +------------------------------------+ 1 row in set (0.001 sec)
去讀取 CPU 這個物件 (讀物件時使用 JSON_QUERY 函數).
MariaDB [(none)]> SELECT JSON_QUERY(@JOBJECT,'$.CPU'); +----------------------------------------------------+ | JSON_QUERY(@JVALUE,'$.CPU') | +----------------------------------------------------+ | { "CPU 1": "Intel", "CPU 2": "Intel" } | +----------------------------------------------------+ 1 row in set (0.000 sec)
去讀取 CPU 物件裡的 CPU 1 的值 (讀值時使用 JSON_VALUE 函數).
MariaDB [(none)]> SELECT JSON_VALUE(@JOBJECT,'$.CPU.CPU 1'); +-----------------------------------+ | JSON_VALUE(@JVALUE,'$.CPU.CPU 1') | +-----------------------------------+ | Intel | +-----------------------------------+ 1 row in set (0.000 sec)
當我們使用 * 號讀取多個值的時候用 JSON_EXTRACT 它可以回傳指定路徑(可以指定多個)下的的值 (values),當回傳多個值時會自動包裝成為陣列 (Array).
MariaDB [(none)]> SELECT JSON_EXTRACT(@JOBJECT,'$.*'); +------------------------------------------------------------------------------------------------------------------------------+ | JSON_EXTRACT(@JOBJECT,'$.*') | +------------------------------------------------------------------------------------------------------------------------------+ | ["ASUS", {"CPU 1": "Intel", "CPU 2": "Intel"}, {"MEM 1": "Hynix", "MEM 2": "Hynix", "MEM 3": "Samsung", "MEM 4": "Samsung"}] | +------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.000 sec) MariaDB [(none)]> SELECT JSON_EXTRACT(@JOBJECT,'$.CPU.*'); +----------------------------------+ | JSON_EXTRACT(@JOBJECT,'$.CPU.*') | +----------------------------------+ | ["Intel", "Intel"] | +----------------------------------+ 1 row in set (0.000 sec)
Array Element Selector
To select elements of an array, one can use one of the following:
- [N] selects element number N in the array. The elements are counted from zero.
- [*] selects all elements in the array.
If the current item is an object (instead of an array), nothing will be selected.
下面是一個 JSON 格式(陣列)的範例.
MariaDB [(none)]> SET @JARRAY='[ { "TimeStamp": "01/07/2021 07:56:35 PM", "Status": "ok", "Temp1": 30, "Temp2": 30 }, { "TimeStamp": "01/07/2021 07:56:48 PM", "Status": "ok", "Temp1": 31, "Temp2": 31 }, { "TimeStamp": "01/07/2021 07:57:00 PM", "Status": "ok", "Temp1": 32, "Temp2": 32 } ]';
指定讀取陣列的第一筆資料 (陣列從 0 開始).
MariaDB [(none)]> SELECT JSON_EXTRACT(@JARRAY,'$[0].*'); +------------------------------------------+ | JSON_EXTRACT(@JARRAY,'$[0].*') | +------------------------------------------+ | ["01/07/2021 07:56:35 PM", "ok", 30, 30] | +------------------------------------------+ 1 row in set (0.000 sec) MariaDB [(none)]> SELECT JSON_EXTRACT(@JARRAY,'$[0]'); +-----------------------------------------------------------------------------------+ | JSON_EXTRACT(@JARRAY,'$[0]') | +-----------------------------------------------------------------------------------+ | {"TimeStamp": "01/07/2021 07:56:35 PM", "Status": "ok", "Temp1": 30, "Temp2": 30} | +-----------------------------------------------------------------------------------+ 1 row in set (0.000 sec)
指定讀取陣列的第一筆資料 (陣列從 0 開始)的 Timestamp 值,可以使用 JSON_EXTRACT 或是 JSON_VALUE 函數.
MariaDB [(none)]> SELECT JSON_EXTRACT(@JARRAY,'$[0].TimeStamp'); +----------------------------------------+ | JSON_EXTRACT(@JARRAY,'$[0].TimeStamp') | +----------------------------------------+ | "01/07/2021 07:56:35 PM" | +----------------------------------------+ 1 row in set (0.000 sec) MariaDB [(none)]> SELECT JSON_VALUE(@JARRAY,'$[0].TimeStamp'); +--------------------------------------+ | JSON_VALUE(@JARRAY,'$[0].TimeStamp') | +--------------------------------------+ | 01/07/2021 07:56:35 PM | +--------------------------------------+ 1 row in set (0.000 sec)
讀取陣列中所有 TimeStamp 的值,需使用 JSON_EXTRACT 函數.
MariaDB [(none)]> SELECT JSON_EXTRACT(@JARRAY,'$[*].TimeStamp'); +--------------------------------------------------------------------------------+ | JSON_EXTRACT(@JARRAY,'$[*].TimeStamp') | +--------------------------------------------------------------------------------+ | ["01/07/2021 07:56:35 PM", "01/07/2021 07:56:48 PM", "01/07/2021 07:57:00 PM"] | +--------------------------------------------------------------------------------+ 1 row in set (0.000 sec)
另外一個 JSON 格式(物件+陣列)的範例.
MariaDB [(none)]> SET @JARRAY='{"Sensor": [ { "TimeStamp": "01/07/2021 07:56:35 PM", "Status": "ok", "Temp1": 30, "Temp2": 30 }, { "TimeStamp": "01/07/2021 07:56:48 PM", "Status": "ok", "Temp1": 31, "Temp2": 31 }, { "TimeStamp": "01/07/2021 07:57:00 PM", "Status": "ok", "Temp1": 32, "Temp2": 32 } ]}';
指定讀取物件內陣列第一筆資料 (陣列從 0 開始),需使用 JSON_QUERY 函數.
MariaDB [(none)]> SELECT JSON_QUERY(@JARRAY,'$.Sensor[0]'); +---------------------------------------------------------------------------------------------------------------------------------------------+ | JSON_QUERY(@JARRAY,'$.Sensor[0]') | +---------------------------------------------------------------------------------------------------------------------------------------------+ | { "TimeStamp": "01/07/2021 07:56:35 PM", "Status": "ok", "Temp1": 30, "Temp2": 30 } | +---------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.001 sec)
指定讀取物件內陣列第一筆資料 (陣列從 0 開始)的 Temp1 值,,可以使用 JSON_EXTRACT 或是 JSON_VALUE 函數.
MariaDB [(none)]> SELECT JSON_VALUE(@JARRAY,'$.Sensor[0].Temp1'); +-----------------------------------------+ | JSON_VALUE(@JARRAY,'$.Sensor[0].Temp1') | +-----------------------------------------+ | 30 | +-----------------------------------------+ 1 row in set (0.001 sec) MariaDB [(none)]> SELECT JSON_EXTRACT(@JARRAY,'$.Sensor[0].Temp1'); +-------------------------------------------+ | JSON_EXTRACT(@JARRAY,'$.Sensor[0].Temp1') | +-------------------------------------------+ | 30 | +-------------------------------------------+ 1 row in set (0.000 sec)