このドキュメントでは、Lindorm SQL におけるすべての JSON 関数の使用方法、パラメーター、および例について説明します。
JSON 関数の概要
関数の分類 | 関数名 | 関数の説明 |
JSON コンストラクター関数 | JSON オブジェクトを作成します。 | |
JSON 配列を作成します。 | ||
JSON 抽出関数 | 指定されたパスにある JSON ドキュメントから値を抽出します。 | |
指定されたパスの値を抽出し、文字列に変換します。 | ||
指定されたパスの値を抽出し、long 型整数に変換します。 | ||
指定されたパスの値を抽出し、浮動小数点数に変換します。 | ||
JSON 包含チェック関数 | JSON ドキュメントに、指定されたすべての値またはオブジェクトが含まれているかどうかをチェックします。 | |
JSON ドキュメントに、指定された値またはオブジェクトのいずれかが含まれているかどうかをチェックします。 | ||
JSON 更新関数 | JSON ドキュメントにデータを挿入または更新し、新しいドキュメントを返します。これは、 | |
JSON ドキュメントにデータを挿入し、新しいドキュメントを返します。フィールドが存在しない場合にのみ、新しいフィールドを挿入します。 | ||
JSON ドキュメント内の既存のデータを置き換え、新しいドキュメントを返します。フィールドが存在する場合にのみ、値を更新します。 | ||
指定されたパスにある JSON ドキュメントからデータを削除し、変更後のドキュメントを返します。 | ||
セマンティクスは |
関数の説明
JSON コンストラクター関数
json_object
JSON オブジェクトを作成します。
構文:
json_object(key1, value1, key2, value2, ...)
パラメーター:
key:キー名。文字列である必要があります。value:値。任意の型を指定できます。
例:
-- シンプルなオブジェクトの作成
SELECT json_object('name', 'Alice', 'age', 25);
-- 結果: {"name": "Alice", "age": 25}
-- INSERT 文での使用
UPSERT INTO users (id, data) VALUES (1, json_object('name', 'Charlie', 'city', 'Beijing'));json_array
JSON 配列を作成します。
構文:
json_array(value1, value2, value3, ...)パラメーター:
value:値。スカラー、オブジェクト、または配列を指定できます。
例:
-- シンプルな配列の作成
SELECT json_array('apple', 'banana', 'orange');
-- 結果: ["apple", "banana", "orange"]
-- INSERT 文での使用
UPSERT INTO products (id, tags) VALUES (1, json_array('electronics', 'mobile', 'smartphone'));
JSON 抽出関数
json_extract
指定されたパスにある JSON ドキュメントから値を抽出します。
構文:
json_extract(json_column, 'path')パラメーター:
json_column:JSON 型の列または式。path:JSON パス式。例:$.field、$.array[0]、または$.nested.field。
例:
-- シンプルなフィールドの抽出
SELECT json_extract('{"name": "Alice", "age": 25}', '$.name');
-- 結果: "Alice"
-- ネストされたフィールドの抽出
SELECT json_extract('{"user": {"name": "Bob", "age": 30}}', '$.user.name');
-- 結果: "Bob"
-- 配列要素の抽出
SELECT json_extract('{"skills": ["Java", "Python"]}', '$.skills[0]');
-- 結果: "Java"
-- 配列全体の抽出
SELECT json_extract('{"skills": ["Java", "Python"]}', '$.skills');
-- 結果: ["Java", "Python"]
-- 数値を含む WHERE 句
select * from tb where json_extract(c2, '$.k3.k4') > 5;
-- 文字列を含む WHERE 句
select * from tb where json_extract_string(c2, '$.k2') = '1';型安全な抽出関数:json_extract_type
json_extract_string
指定されたパスの値を抽出し、文字列に変換します。パスの値が文字列でない場合、デフォルトで NULL を返します。
SELECT json_extract_string('{"name": "Alice"}', '$.name');
-- 結果: Alice (VARCHAR 型)
SELECT json_extract_string('{"number": "30"}', '$.name');
-- 結果: NULL。(型が Number であり、一致しません。)json_extract_long
指定されたパスの値を抽出し、long 型整数に変換します。パスの値が数値でない場合、Java Database Connectivity (JDBC) はエラーをスローします。
SELECT json_extract_long('{"id": 123456789}', '$.id');
-- 結果: 123456789 (LONG 型)
SELECT json_extract_long('{"id": 123456.789}', '$.id');
-- エラーがスローされます
SELECT json_extract_long('{"id": "123456.789"}', '$.id');
-- エラーがスローされますjson_extract_double
指定されたパスの値を抽出し、浮動小数点数に変換します。パスの値が浮動小数点数でない場合、JDBC はエラーをスローします。
SELECT json_extract_double('{"id": 12345.56}', '$.id');
-- 結果: 12345.56 (Double 型)
SELECT json_extract_double('{"id": 12345}', '$.id');
-- 結果: 12345.0 (Double 型)
SELECT json_extract_double('{"id": "123456.789"}', '$.id');
-- エラーがスローされますこれら 3 つの関数は厳密に型付けされています。指定されたパスの要素は、関数の型と厳密に一致する必要があります。一致しない場合、関数は NULL を返すか、エラーをスローします。クラスターを設定して型変換を強制することもできますが、推奨されません。混合型は予期しない論理的な問題を引き起こす可能性があるため、JSON データを挿入する前にデータ型を定義することを推奨します。
JSON 包含チェック関数
json_contains
JSON ドキュメントに、指定されたすべての値またはオブジェクトが含まれているかどうかをチェックします。
構文:
json_contains(target, candidate[, path])パラメーター:
target_json:必須。JSON ドキュメント。candidate_json:必須。チェック対象の JSON ドキュメント。path:任意。パス式。
パラメーターの詳細については、「パラメーターの追加情報」をご参照ください。
戻り値:
1(true):指定された値が見つかった場合。0(false):ターゲットに候補が含まれていない場合。
json_contains 関数は、target_json ドキュメントが candidate_json ドキュメントを含む場合は 1 を、それ以外の場合は 0 を返します。 path パラメーターを指定した場合、この関数は、指定された path のデータに candidate_json ドキュメントが含まれているかどうかを確認します。
json_contains 関数は、以下の場合に NULL を返します:
指定されたパスが JSON ドキュメントに存在しない。
いずれかのパラメーターが
NULLである。
例:
-- テーブルの作成とデータの挿入
CREATE TABLE test_table (id INT, c1 VARCHAR, data JSON, PRIMARY KEY(id));
UPSERT INTO test_table (id, data) VALUES (1, NULL);
UPSERT INTO test_table (id, data) VALUES (2, '{"skills": ["Java", "Python"]}');
UPSERT INTO test_table (id, data) VALUES (3, '{"skills": ["Go", "C"]}');
UPSERT INTO test_table (id, data) VALUES (4, '{"technical_skills": ["Java", "Go", "Rust"]}');
UPSERT INTO test_table (id, data) VALUES (5, '["Java","C++", "JavaScript"]');
UPSERT INTO test_table (id, data) VALUES (6, '{"skills": "Java"}');
UPSERT INTO test_table (id, data) VALUES (7, '["Java", "C#"]');
UPSERT INTO test_table (id, data) VALUES (8, '{"skills": ["Go", "Rust"]}');-- 2 つのパラメーター形式。デフォルトのパスは「$」です。
mysql> SELECT id, data FROM test_table WHERE json_contains(data, '["Java"]') and id>0 and id<10;
+------+------------------------------+
| id | data |
+------+------------------------------+
| 5 | ["Java","C++", "JavaScript"] |
| 7 | ["Java", "C#"] |
+------+------------------------------+
2 rows in set (0.01 sec)
-- 3 つのパラメーター形式:指定されたパスをチェック
mysql> SELECT id, data FROM test_table WHERE json_contains(data, '["Java"]', '$.skills') and id>0 and id<10;
+------+--------------------------------+
| id | data |
+------+--------------------------------+
| 2 | {"skills": ["Java", "Python"]} |
+------+--------------------------------+
1 row in set (0.01 sec)
-- "Java" と "Go" の両方を含む
mysql> SELECT id, data FROM test_table WHERE json_contains(data, '["Java","Go"]', '$.skills') and id>0 and id<10;
Empty set (0.02 sec)
-- 配列または要素にスカラー "Java" を含む
mysql> SELECT id, data FROM test_table WHERE json_contains(data, '"Java"', '$.skills') and id>0 and id<10;
+------+--------------------------------+
| id | data |
+------+--------------------------------+
| 2 | {"skills": ["Java", "Python"]} |
| 6 | {"skills": "Java"} |
+------+--------------------------------+
2 rows in set (0.01 sec)
-- 配列要素にスカラー "Java" のみを含む配列が含まれている。(id=6 の場合、パスの JSON ドキュメントはスカラーです。スカラーのサブセットはスカラーのみであり、配列にはできません。)
mysql> SELECT id, data FROM test_table WHERE json_contains(data, '["Java"]', '$.skills') and id>0 and id<10;
+------+--------------------------------+
| id | data |
+------+--------------------------------+
| 2 | {"skills": ["Java", "Python"]} |
+------+--------------------------------+
1 row in set (0.01 sec)
-- ドキュメント全体にオブジェクトが含まれているかチェック
SELECT json_contains('{"a": 1, "b": 2}', '{"a": 1}');
-- 結果: 1
-- 指定されたパスに値が含まれているかチェック
SELECT json_contains('{"a": 1, "b": 2}', '1', '$.a');
-- 結果: 1
SELECT json_contains('{"a": 1, "b": 2}', '1', '$.b');
-- 結果: 0
-- 配列内の包含をチェック
SELECT json_contains('{"skills": ["Java", "Python"]}', '"Java"', '$.skills');
-- 結果: 1パラメーターの追加情報
candidate_jsonは JSON ドキュメントです。対応する要素を JSON 文字列として表現する必要があります。数値 10 を含む JSON ドキュメント:
'10'文字列 "10" を含む JSON ドキュメント:
'"10"'数値のリストを含む JSON ドキュメント:
'[1,2,3]'文字列のリストを含む JSON ドキュメント:
'["10","abc","key"]'
スカラーのサブセットはスカラーのみです。配列のサブセットは要素または配列です。
JSON の型分類:
スカラー:文字列、数値 (整数/倍精度)、ブール値、Null
複合型:配列、オブジェクト
チェック条件
json_contains_any(skills, '["Java"]', '$.technical_skills')を考えます。$.technical_skillsパスの JSON について:値が
{"technical_skills":"Java"}の場合、関数はfalseを返します。文字列のサブセットをリストにすることはできません。値が
{"technical_skills":["Java"]}または{"technical_skills":["Java","Go"]}の場合、関数はtrueを返します。
チェック条件
json_contains_any(skills, '"Java"', '$.technical_skills')を考えます。$.technical_skillsパスの JSON について:値が
{"technical_skills":"Java"}の場合、関数はtrueを返します。値が
{"technical_skills":["Java"]}または{"technical_skills":["Java","Go"]}の場合、関数はtrueを返します。
json_contains_any
JSON ドキュメントに、指定された値またはオブジェクトのいずれかが含まれているかどうかをチェックします。
構文:
構文は json_contains と同じです。違いの詳細については、「JSON 包含チェック関数の比較」をご参照ください。
例:
mysql> select json_contains_any('{"skills": ["Java", "Python"]}', '["Java", "Go"]');
+--------+
| EXPR$0 |
+--------+
| 0 |
+--------+
1 row in set (0.02 sec)
mysql> select json_contains_any('{"skills": ["Java", "Python"]}', '["Java", "Go"]','$.skills');
+--------+
| EXPR$0 |
+--------+
| 1 |
+--------+
1 row in set (0.03 sec)
-- デフォルトの 2 つのパラメーター形式。パスはデフォルトで「$」です。
mysql> SELECT id, data FROM test_table WHERE json_contains_any(data, '["Java", "Go"]') limit 10;
+------+------------------------------+
| id | data |
+------+------------------------------+
| 5 | ["Java","C++", "JavaScript"] |
| 7 | ["Java", "C#"] |
+------+------------------------------+
2 rows in set (0.01 sec)
-- 3 つのパラメーター形式
mysql> SELECT id, data FROM test_table WHERE json_contains_any(data, '["Java", "Go", "Rust"]', '$.skills') limit 10;
+------+--------------------------------+
| id | data |
+------+--------------------------------+
| 2 | {"skills": ["Java", "Python"]} |
| 3 | {"skills": ["Go", "C"]} |
| 6 | {"skills": "Java"} |
| 8 | {"skills": ["Go", "Rust"]} |
+------+--------------------------------+
4 rows in set (0.01 sec)
-- 配列のいずれかの値が含まれているかチェック
SELECT json_contains_any('{"skills": ["Java", "Python"]}', '["Java", "Go"]');
-- 結果: 0
SELECT json_contains_any('{"skills": ["Java", "Python"]}', '["Java", "Go"]','$.skills');
-- 結果: 1
-- 指定されたパスでチェック
SELECT json_contains_any('{"departments": ["Engineering", "Sales"]}', '["Marketing", "Engineering"]', '$.departments');
-- 結果: 1JSON 更新関数
json_set
JSON ドキュメントにデータを挿入または更新し、変更後のドキュメントを返します。この関数は json_insert + json_replace に相当します。
構文:
json_set(json_column, 'path', new_value)動作:
指定されたパスが存在する場合、この関数はそのパスの値を更新します。
指定されたパスが存在しない場合、この関数はそのパスに値を挿入します。
JSON 列が NULL の場合、結果も NULL になります。操作は実行されません。
例:
-- 既存フィールドの更新
UPSERT INTO test_table (id, data) VALUES (3, '{"name": "Charlie", "age": 30}');
UPDATE test_table SET data = json_set(data, '$.age', 31) WHERE id = 3;
-- 結果: {"name": "Charlie", "age": 31}
-- 新しいフィールドの挿入
UPDATE test_table SET data = json_set(data, '$.department', 'Engineering') WHERE id = 3;
-- 結果: {"name": "Charlie", "age": 31, "department": "Engineering"}
-- JSON 列が NULL の場合 (json_upsert との主な違い)
UPSERT INTO test_table (id,c1) VALUES (4,'test');
UPDATE test_table SET data = json_set(data, '$.name', 'David') WHERE id = 4;
-- 結果: NULLjson_insert
JSON ドキュメントにデータを挿入し、変更後のドキュメントを返します。この関数は、指定されたパスに値が存在しない場合にのみ新しい値を挿入します。
構文:
json_insert(json_column, 'path', new_value)動作:
指定されたパスが存在しない場合、この関数はそのパスに値を挿入します。
指定されたパスが既に存在する場合、この関数は操作を実行しません。
例:
-- 新しいフィールドの挿入
UPSERT INTO test_table (id, data) VALUES (5, '{"name": "Eve"}');
UPDATE test_table SET data = json_insert(data, '$.age', 28) WHERE id = 5;
-- 結果: {"name": "Eve", "age": 28}
-- 既存フィールドの挿入試行 (効果なし)
UPDATE test_table SET data = json_insert(data, '$.name', 'New Name') WHERE id = 5;
-- 結果: {"name": "Eve", "age": 28} (name フィールドは変更されません)json_replace
JSON ドキュメント内の既存のデータを置き換え、変更後のドキュメントを返します。この関数は、指定されたパスに値が存在する場合にのみ値を更新します。
構文:
json_replace(json_column, 'path', new_value)動作:
指定されたパスが存在する場合、この関数はそのパスの値を更新します。
指定されたパスが存在しない場合、この関数は操作を実行しません。
例:
-- 既存フィールドの更新
UPSERT INTO test_table (id, data) VALUES (6, '{"name": "Frank", "age": 35}');
UPDATE test_table SET data = json_replace(data, '$.age', 36) WHERE id = 6;
-- 結果: {"name": "Frank", "age": 36}
-- 存在しないフィールドの更新試行 (効果なし)
UPDATE test_table SET data = json_replace(data, '$.city', 'Shanghai') WHERE id = 6;
-- 結果: {"name": "Frank", "age": 36} (city フィールドなし)json_remove
指定されたパスにある JSON ドキュメントからデータを削除し、変更後のドキュメントを返します。
構文:
json_remove(json_column, 'path')動作:
指定されたパスが存在する場合、この関数はそのパスのデータを削除します。
指定されたパスが存在しない場合、これは安全な操作であり、エラーは発生しません。
例:
-- フィールドの削除
UPSERT INTO test_table (id, data) VALUES (7, '{"name": "Grace", "temp_field": "to_remove"}');
UPDATE test_table SET data = json_remove(data, '$.temp_field') WHERE id = 7;
-- 結果: {"name": "Grace"}
-- 存在しないフィールドの削除 (安全)
UPDATE test_table SET data = json_remove(data, '$.nonexistent') WHERE id = 7;
-- 結果: {"name": "Grace"} (エラーなし)json_upsert
この関数はセマンティクスは json_set と同じですが、NULL 値を処理できます。
構文:
json_upsert(json_column, 'path', new_value)
動作:
JSON 列が NULL の場合、この関数は新しいオブジェクト
{path: new_value}を作成します。指定されたパスが存在する場合、この関数はそのパスの値を更新します。
指定されたパスが存在しない場合、この関数はそのパスに値を挿入します。
例:
-- JSON 列が NULL の場合
CREATE TABLE test_table (id INT, c1 VARCHAR, data JSON, PRIMARY KEY(id));
UPSERT INTO test_table (id,c1) VALUES (1,'test');
UPDATE test_table SET data = json_upsert(data, '$.name', 'Alice') WHERE id = 1;
-- 結果: {"name": "Alice"}
-- 既存のフィールドを更新
UPSERT INTO test_table (id, data) VALUES (2, '{"name": "Bob", "age": 25}');
UPDATE test_table SET data = json_upsert(data, '$.age', 26) WHERE id = 2;
-- 結果: {"name": "Bob", "age": 26}
-- 新しいフィールドを挿入
UPDATE test_table SET data = json_upsert(data, '$.city', 'Beijing') WHERE id = 2;
-- 結果: {"name": "Bob", "age": 26, "city": "Beijing"}これらの JSON 更新関数の違いの詳細については、「JSON 更新関数の比較」をご参照ください。
関数の比較まとめ
JSON 包含チェック関数の比較
関数 | 違い |
|
つまり、 |
|
つまり、 |
JSON 更新関数の比較
関数 | NULL 列の処理 | フィールドが存在する場合 | フィールドが存在しない場合 | 主なユースケース |
| NULL のまま | 更新 | 挿入 | NULL でないことがわかっている列を更新します。(MySQL のセマンティクスに準拠)。 |
| 新しいオブジェクトを作成 | 更新 | 挿入 | 汎用的な更新。列が NULL の場合でも挿入します。 |
| NULL のまま | 操作なし | 挿入 | 新しいフィールドのみを挿入します。 |
| NULL のまま | 更新 | 操作なし | 既存のフィールドのみを更新します。 |
| NULL のまま | 削除 | 操作なし | フィールドを削除します。 |
関数ベースのインデックスのサポート
構文
create_index_statement ::= CREATE INDEX [ index_name ]
ON table_name '(' index_identifier ')'
[INCLUDE include_identifier]
[ASYNC]
[ index_options ]
index_identifier ::= '('json_extract_type(column, json_path)')'
include_identifier ::= '('column_name1,...,column_namen ')'パラメーターの説明
パラメーター | 説明 |
index_name | インデックステーブルの名前。 |
table_name | ワイドテーブルの名前。 |
json_extract_type | JSON 列から特定のデータ型のフィールドを抽出し、セカンダリインデックスとして使用します。データ型が一致しない場合、セカンダリインデックスは構築されません。以下の関数型がサポートされています:
|
column | JSON 列の名前。 |
json_path | JSON 列内のパス。指定されたパスの値を抽出するために使用されます。 |
ASYNC | インデックスを非同期で構築します。ASYNC を追加しない場合、インデックスは同期的に構築されます。 |
JSON 関数の検索インデックスサポートの詳細については、「Lindorm JSON 型の検索インデックスの使用」をご参照ください。
サポートされている関数
以下の JSON 関数は、関数ベースのインデックスの作成をサポートしています:
json_extract および json_extract_type に関連するクエリの高速化
json_extract_string(json_column, 'path')json_extract_long(json_column, 'path')json_extract_double(json_column, 'path')
Lindorm ワイドテーブル SQL では、JSON データ型の列内の特定のパスにあるデータに対してセカンダリインデックスを作成できます。ただし、セカンダリインデックスを構築する際には、JSON 列に対する json_extract 関数の型を指定する必要があります。
json_contains に関連するクエリの高速化
json_contains(json_column, 'value', 'path')
現在、value と path パラメーターは固定値である必要があります。クエリ条件は静的でなければなりません。
インデックス作成の例
-- json_contains のインデックスを作成
CREATE INDEX idx_user_role ON test_table (json_contains(data, '"admin"', '$.roles')) INCLUDE(data) SYNC;
-- json_extract_string のインデックスを作成
CREATE INDEX idx_user_city ON test_table (json_extract_string(data, '$.address.city')) INCLUDE(data) SYNC;
-- 列を含めずに json_extract_string のインデックスを作成
CREATE INDEX idx_user_city ON test_table (json_extract_string(data, '$.address.city'));
-- json_extract_long のインデックスを作成
CREATE INDEX idx_user_age ON test_table (json_extract_long(data, '$.age')) INCLUDE(data) SYNC;
-- インデックス作成結果の表示
SHOW INDEX FROM test_table;制限事項
JsonPath を使用する際は、常に標準構文に従ってください。
複雑な JSON 操作によるパフォーマンスへの影響に注意してください。
頻繁にクエリされるパスには、インデックスを作成してクエリの応答速度を向上させることができます。
一般的なエラーハンドリング
無効な JSON パス
JsonPathが有効なJsonPathではない場合、illegal json pathエラーが発生します。 詳細については、「MySQL のJsonPathの定義」をご参照ください。無効な JSON 値
json_contain candidate is not a valid value:candidateパラメーターが有効な JSON 文字列であることを確認してください。全表スキャン警告
This query may be a full table scan and thus may have unpredictable performance:この警告は、非効率な全表スキャンを示しています。インデックスを作成してクエリを高速化するか、`LIMIT` 句を追加してデータのサブセットをフィルター処理することができます。
推奨事項
適切な更新関数の選択
ビジネスニーズに応じて
json_upsertまたはjson_setを選択できます。インデックス計画
頻繁にクエリされる JSON パスに対して、関数ベースのインデックスを作成できます。
型安全性
型固有の抽出関数を使用して、データ型の正確性を確保できます。数値と数値文字列を混在させると曖昧さが生じるため、避けてください。例えば、数値の 10 と文字列の "10" を混在させないでください。