すべてのプロダクト
Search
ドキュメントセンター

Lindorm:JSON 関数

最終更新日:Mar 29, 2026

Lindorm SQL は、JSON 列に格納された JSON データを構築、抽出、包含チェック、更新するための JSON 関数を提供します。このリファレンスでは、各関数の構文、パラメーター、動作、および例について説明します。

関数の概要

カテゴリ関数説明
コンストラクタjson_objectJSON オブジェクトを作成します。
コンストラクタjson_arrayJSON 配列を作成します。
抽出json_extract指定されたパスの値を抽出します。
抽出json_extract_string指定されたパスの値を抽出し、VARCHAR として返します。
抽出json_extract_long指定されたパスの値を抽出し、LONG として返します。
抽出json_extract_double指定されたパスの値を抽出し、Double として返します。
包含チェックjson_containsJSON ドキュメントが指定されたすべての値を含む場合、1 を返します。
包含チェックjson_contains_anyJSON ドキュメントが指定された値のいずれかを含む場合、1 を返します。
更新json_setパスに値を挿入または更新します。json_insert + json_replace に相当します。
更新json_insertパスが存在しない場合にのみ、パスに値を挿入します。
更新json_replaceパスが既に存在する場合にのみ、パスの値を更新します。
更新json_remove指定されたパスの値を削除します。
更新json_upsertjson_set と同じですが、JSON 列が NULL の場合に新しいオブジェクトを作成します。

JSON パス式

すべての抽出、包含チェック、および更新関数は、JSON ドキュメント内の場所を特定するために JSON パス式を受け取ります。

記号説明
$ドキュメントルート$
.keyオブジェクトメンバーアクセス$.name
[n]配列要素アクセス (0 から始まるインデックス)$.skills[0]
.nested.keyネストされたフィールドアクセス$.address.city

JSON ドキュメントの例:

{
  "name": "Alice",
  "age": 25,
  "address": { "city": "Beijing" },
  "skills": ["Java", "Python"]
}
パス結果
$.name"Alice"
$.age25
$.address.city"Beijing"
$.skills[0]"Java"
$.skills["Java", "Python"]

コンストラクタ関数

json_object

キーと値のペアから JSON オブジェクトを作成します。

構文

json_object(key1, value1, key2, value2, ...)

パラメーター

パラメーター説明
keyキー名。文字列である必要があります。
value値。任意の型を指定できます。

単純なオブジェクトを作成します:

SELECT json_object('name', 'Alice', 'age', 25);
-- 結果: {"name": "Alice", "age": 25}

UPSERT 文で使用します:

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"]

UPSERT 文で使用します:

UPSERT INTO products (id, tags) VALUES (1, json_array('electronics', 'mobile', 'smartphone'));

抽出関数

すべての抽出関数は、JSON 列とパス式を受け取ります。3つの型指定の抽出関数 (json_extract_stringjson_extract_longjson_extract_double) は厳密に型付けされており、パスの値は関数の期待する型と一致する必要があります。型が一致しない場合、関数は NULL を返すか、エラーをスローします。混合型による予期しない動作を避けるために、JSON データを挿入する前にデータ型を定義してください。

json_extract

JSON ドキュメントから指定されたパスの値を抽出し、そのネイティブ JSON 型で返します。

構文

json_extract(json_column, 'path')

パラメーター

パラメーター説明
json_columnJSON 型の列または式。
pathJSON パス式。例:$.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 句で使用します (型安全のため json_extract_string を使用します):

SELECT * FROM tb WHERE json_extract_string(c2, '$.k2') = '1';

json_extract_string

指定されたパスの値を抽出し、VARCHAR として返します。パスの値が文字列でない場合、関数は NULL を返します。

$.name の値は文字列なので、VARCHAR を返します:

SELECT json_extract_string('{"name": "Alice"}', '$.name');
-- 結果: Alice (VARCHAR)

$.number の値は数値であり、文字列ではないため、関数は NULL を返します:

SELECT json_extract_string('{"number": 30}', '$.number');
-- 結果: NULL

json_extract_long

指定されたパスの値を抽出し、LONG として返します。パスの値が数値でない場合、Java Database Connectivity (JDBC) はエラーをスローします。

値は整数なので、LONG を返します:

SELECT json_extract_long('{"id": 123456789}', '$.id');
-- 結果: 123456789 (LONG)

値は浮動小数点数です — JDBC はエラーをスローします:

SELECT json_extract_long('{"id": 123456.789}', '$.id');
-- エラーをスローします

値は数値文字列です — JDBC はエラーをスローします:

SELECT json_extract_long('{"id": "123456.789"}', '$.id');
-- エラーをスローします

json_extract_double

指定されたパスの値を抽出し、Double として返します。パスの値が浮動小数点数でない場合、JDBC はエラーをスローします。

値は浮動小数点数なので、Double を返します:

SELECT json_extract_double('{"id": 12345.56}', '$.id');
-- 結果: 12345.56 (Double)

値は整数です — 関数はそれを Double として返します:

SELECT json_extract_double('{"id": 12345}', '$.id');
-- 結果: 12345.0 (Double)

値は数値文字列です — JDBC はエラーをスローします:

SELECT json_extract_double('{"id": "123456.789"}', '$.id');
-- エラーをスローします

包含チェック関数

json_contains

target_jsoncandidate_json のすべての要素を含む場合は 1 を、そうでない場合は 0 を返します。オプションで、パスを指定してドキュメント内の特定の場所で包含をチェックできます。

指定されたパスが存在しない場合、またはいずれかのパラメーターが NULL の場合は NULL を返します。

構文

json_contains(target_json, candidate_json[, path])

パラメーター

パラメーター必須説明
target_jsonはい検索対象の JSON ドキュメント。
candidate_jsonはいチェック対象の JSON ドキュメント。有効な JSON 文字列である必要があります。
pathいいえtarget_json 内でチェックするパス。デフォルトは $ (ルート) です。

`candidate_json` のフォーマット方法

candidate_json は、チェック対象の要素を表す有効な JSON 文字列である必要があります:

チェック対象candidate_json の値
数値 10'10'
文字列 "10"'"10"'
数値のリスト'[1,2,3]'
文字列のリスト'["10","abc","key"]'

JSON 型の分類

  • スカラー:文字列、数値 (整数/Double)、ブール値、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つのパラメーター形式では、ドキュメント全体 (ルートパス $) をチェックします。これにより、トップレベルのドキュメントが "Java" を含む配列である行が見つかります:

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#"]               |
+------+------------------------------+

3つのパラメーター形式では、特定のパスをチェックします。これにより、$.skills"Java" を含む配列である行が見つかります:

SELECT id, data FROM test_table WHERE json_contains(data, '["Java"]', '$.skills') AND id > 0 AND id < 10;
+------+--------------------------------+
| id   | data                           |
+------+--------------------------------+
|    2 | {"skills": ["Java", "Python"]} |
+------+--------------------------------+

json_containscandidate_json のすべての要素が存在することを要求します。このクエリでは、$.skills 配列に "Java""Go" の両方を含む行がないため、行は見つかりません:

SELECT id, data FROM test_table WHERE json_contains(data, '["Java","Go"]', '$.skills') AND id > 0 AND id < 10;
-- 空のセット

候補としてスカラーの "Java" を使用すると、"Java" を含む配列と、"Java" に等しいスカラーの両方に一致します:

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"}             |
+------+--------------------------------+

オブジェクトがキーと値のペアを含むかどうかをチェックします:

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

json_contains_any

target_jsoncandidate_json の少なくとも1つの要素を含む場合、1 を返します。json_contains と同じ構文とパラメーターを使用します。

パスなしでは、ルートドキュメントをチェックします。トップレベルのドキュメントはオブジェクトであり、"Java" または "Go" を直接含む配列ではありません:

SELECT json_contains_any('{"skills": ["Java", "Python"]}', '["Java", "Go"]');
-- 結果: 0

パスを指定すると、$.skills をチェックします。$.skills の配列には "Java" が含まれており、これは候補の1つの要素と一致します:

SELECT json_contains_any('{"skills": ["Java", "Python"]}', '["Java", "Go"]', '$.skills');
-- 結果: 1

2つのパラメーター形式では、トップレベルのドキュメントが ["Java", "Go"] のいずれかの要素を持つ配列である行が見つかります:

SELECT id, data FROM test_table WHERE json_contains_any(data, '["Java", "Go"]') LIMIT 10;
+------+------------------------------+
| id   | data                         |
+------+------------------------------+
|    5 | ["Java","C++", "JavaScript"] |
|    7 | ["Java", "C#"]               |
+------+------------------------------+

3つのパラメーター形式では、$.skills が候補リストのいずれかの要素を含む行が見つかります:

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"]}     |
+------+--------------------------------+

特定のパスが候補配列のいずれかの値を含むかどうかをチェックします:

SELECT json_contains_any('{"departments": ["Engineering", "Sales"]}', '["Marketing", "Engineering"]', '$.departments');
-- 結果: 1

パスにおけるスカラーと配列の包含の理解

json_contains_any(data, '["Java"]', '$.technical_skills') を考えます。動作は $.technical_skills の JSON 型に依存します:

  • 値が {"technical_skills": "Java"} (スカラー文字列) の場合、関数は false を返します。スカラーのサブセットはリストにはなりえません。

  • 値が {"technical_skills": ["Java"]} または {"technical_skills": ["Java", "Go"]} (配列) の場合、関数は true を返します。

json_contains_any(data, '"Java"', '$.technical_skills') を考えます。スカラー候補を使用する場合:

  • 値が {"technical_skills": "Java"} ("Java" に等しいスカラー文字列) の場合、関数は true を返します。

  • 値が {"technical_skills": ["Java"]} または {"technical_skills": ["Java", "Go"]} ("Java" を含む配列) の場合、関数は true を返します。

更新関数

json_set

指定されたパスに値を挿入または更新します。パスが存在する場合は値を更新し、パスが存在しない場合は値を挿入します。JSON 列が NULL の場合、結果は NULL になります — 新しいオブジェクトは作成されません。

json_insert + json_replace に相当します。

構文

json_set(json_column, 'path', new_value)

既存のフィールドを更新します:

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 の場合、結果は NULL のままです:

UPSERT INTO test_table (id, c1) VALUES (4, 'test');
UPDATE test_table SET data = json_set(data, '$.name', 'David') WHERE id = 4;
-- 結果: NULL

json_insert

指定されたパスがまだ存在しない場合にのみ、値を挿入します。パスが既に存在する場合、関数は何も実行しません。

json_insert は既存の値を上書きしません。既存のフィールドへの挿入試行は、何もせずに元の値を保持します。

構文

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}

既存のフィールドへの挿入試行は効果がありません — name フィールドは変更されません:

UPDATE test_table SET data = json_insert(data, '$.name', 'New Name') WHERE id = 5;
-- 結果: {"name": "Eve", "age": 28}

json_replace

指定されたパスが既に存在する場合にのみ、値を更新します。パスが存在しない場合、関数は何も実行しません。

構文

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}

存在しないフィールドの更新試行は効果がありません — city フィールドは追加されません:

UPDATE test_table SET data = json_replace(data, '$.city', 'Shanghai') WHERE id = 6;
-- 結果: {"name": "Frank", "age": 36}

json_remove

指定されたパスの値を削除し、変更されたドキュメントを返します。パスが存在しない場合、操作はエラーなしで成功します。

構文

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 のように動作しますが、1つの重要な違いがあります:JSON 列が NULL の場合、json_upsert は NULL を返す代わりに新しい JSON オブジェクトを作成します。

構文

json_upsert(json_column, 'path', new_value)

JSON 列が NULL の場合、json_upsert は新しいオブジェクトを作成します:

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_containscandidate_json のすべての要素が target_json に含まれている必要があります (candidate_jsontarget_json のサブセットです)。
json_contains_anycandidate_json の少なくとも1つの要素が target_json に含まれている必要があります。

更新関数

関数NULL 列パスが存在する場合パスが存在しない場合使用場面
json_setNULL のまま更新挿入列が NULL でないことがわかっている場合。MySQL のセマンティクスと一致します。
json_upsert作成します {path: value}更新挿入列が NULL の可能性がある場合を含む、汎用の更新。
json_insertNULL のまま操作なし挿入既存の値を変更せずに新しいフィールドを追加する場合。
json_replaceNULL のまま更新操作なし新しいフィールドを挿入せずに既存のフィールドを更新する場合。
json_removeNULL のまま削除操作なしフィールドを削除する場合。

関数ベースインデックス

ワイドテーブル内の特定の JSON パスに対するクエリを高速化するために、関数ベースインデックスを作成します。

構文

CREATE INDEX [index_name]
    ON table_name (json_extract_type(column, json_path))
  [INCLUDE (column_name1, ..., column_namen)]
  [ASYNC]
  [index_options]

パラメーター

パラメーター説明
index_nameインデックステーブルの名前。
table_nameワイドテーブルの名前。
json_extract_typeインデックス付けされるパスを定義する抽出関数。サポートされている関数:json_extract_stringjson_extract_longjson_extract_double。抽出された値のデータ型が関数の戻り値の型と一致しない場合、その行に対してセカンダリインデックスは作成されません。
columnJSON 列の名前。
json_pathJSON 列内でインデックス付けするパス。
ASYNCインデックスを非同期で作成します。ASYNC を指定しない場合、インデックスは同期的に作成されます。

サポートされている関数

以下の関数は、関数ベースインデックスの作成をサポートしています:

  • json_extract_string(json_column, 'path') — 文字列値にインデックスを作成します

  • json_extract_long(json_column, 'path') — 長整数値にインデックスを作成します

  • json_extract_double(json_column, 'path') — 浮動小数点値にインデックスを作成します

  • json_contains(json_column, 'value', 'path') — 包含チェックにインデックスを作成します。valuepath パラメーターは固定 (静的) 値である必要があります

json_contains クエリを $.roles で高速化するためのインデックスを作成します:

CREATE INDEX idx_user_role ON test_table (json_contains(data, '"admin"', '$.roles')) INCLUDE(data) SYNC;

$.address.city の文字列フィールドにインデックスを作成します:

CREATE INDEX idx_user_city ON test_table (json_extract_string(data, '$.address.city')) INCLUDE(data) SYNC;

追加の列を含めずに文字列フィールドにインデックスを作成します:

CREATE INDEX idx_user_city ON test_table (json_extract_string(data, '$.address.city'));

$.age の数値フィールドにインデックスを作成します:

CREATE INDEX idx_user_age ON test_table (json_extract_long(data, '$.age')) INCLUDE(data) SYNC;

インデックスが作成されたことを確認します:

SHOW INDEX FROM test_table;

JSON 検索インデックスのサポートについては、「Lindorm JSON 型の検索インデックスの使用」をご参照ください。

制限事項

  • 常に有効な JSON パス構文を使用してください。パス式が無効な場合、illegal json path エラーが発生します。パス構文の詳細については、「MySQL の JsonPath 定義」をご参照ください。

  • 複雑な JSON 操作は、パフォーマンスに大きなオーバーヘッドをもたらす可能性があります。頻繁にクエリされるパスには、関数ベースインデックスを作成してください。

トラブルシューティング

エラー原因修正
illegal json pathパス式が有効な JSON パス構文ではありません。MySQL JsonPath 定義」に対してパス構文を確認してください。
json_contain candidate is not a valid valuecandidate パラメーターが有効な JSON 文字列ではありません。候補の値が JSON 文字列として正しくフォーマットされていることを確認してください。
This query may be a full table scan and thus may have unpredictable performanceクエリはインデックスを使用できず、全表スキャンを実行します。クエリ対象のパスに関数ベースインデックスを作成するか、LIMIT 句を追加して結果セットを減らしてください。

ベストプラクティス

適切な更新関数を選択する。JSON 列が NULL の可能性がある場合や、汎用の挿入または更新動作が必要な場合は、json_upsert を使用してください。列が NULL でないことがわかっており、MySQL 互換のセマンティクスが必要な場合は、json_set を使用してください。

頻繁にクエリされるパスにインデックスを作成する。WHERE 句や json_contains 条件に現れる JSON パスには、関数ベースインデックスを作成してください。これにより、全表スキャンを回避し、クエリのパフォーマンスを大幅に向上させることができます。

型安全のために型指定の抽出関数を使用する。特定の戻り値の型が必要な場合は、json_extract の代わりに json_extract_stringjson_extract_longjson_extract_double を使用してください。JSON データを挿入する前にデータ型を一貫して定義してください — 数値と数値文字列 (例:数値 10 と文字列 "10") を混在させると、あいまいな動作や予期しないクエリ結果を引き起こします。