All Products
Search
Document Center

Lindorm:Fungsi JSON

Last Updated:Mar 29, 2026

Lindorm SQL menyediakan fungsi JSON untuk membuat, mengekstraksi, memeriksa keberadaan, dan memperbarui data JSON yang disimpan dalam kolom JSON. Referensi ini menjelaskan sintaksis, parameter, perilaku, serta contoh setiap fungsi.

Ikhtisar fungsi

KategoriFungsiDeskripsi
Constructorjson_objectMembuat objek JSON.
Constructorjson_arrayMembuat array JSON.
Extractionjson_extractMengekstraksi nilai pada path yang ditentukan.
Extractionjson_extract_stringMengekstraksi nilai pada path yang ditentukan dan mengembalikannya sebagai VARCHAR.
Extractionjson_extract_longMengekstraksi nilai pada path yang ditentukan dan mengembalikannya sebagai LONG.
Extractionjson_extract_doubleMengekstraksi nilai pada path yang ditentukan dan mengembalikannya sebagai Double.
Containment checkjson_containsMengembalikan 1 jika dokumen JSON berisi semua nilai yang ditentukan.
Containment checkjson_contains_anyMengembalikan 1 jika dokumen JSON berisi salah satu dari nilai yang ditentukan.
Updatejson_setMenyisipkan atau memperbarui nilai pada suatu path. Setara dengan json_insert + json_replace.
Updatejson_insertMenyisipkan nilai pada suatu path hanya jika path tersebut belum ada.
Updatejson_replaceMemperbarui nilai pada suatu path hanya jika path tersebut sudah ada.
Updatejson_removeMenghapus nilai pada path yang ditentukan.
Updatejson_upsertSama seperti json_set, tetapi membuat objek baru jika kolom JSON bernilai NULL.

Ekspresi path JSON

Semua fungsi ekstraksi, pemeriksaan keberadaan, dan pembaruan menerima ekspresi path JSON untuk mengidentifikasi lokasi dalam dokumen JSON.

SimbolDeskripsiContoh
$Akar dokumen$
.keyAkses anggota objek$.name
[n]Akses elemen array (indeks dimulai dari 0)$.skills[0]
.nested.keyAkses bidang bersarang$.address.city

Contoh dokumen JSON:

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

Fungsi constructor

json_object

Membuat objek JSON dari pasangan kunci-nilai.

Sintaksis

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

Parameter

ParameterDeskripsi
keyNama kunci. Harus berupa string.
valueNilainya. Dapat berupa tipe apa pun.

Contoh

Buat objek sederhana:

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

Gunakan dalam pernyataan UPSERT:

UPSERT INTO users (id, data) VALUES (1, json_object('name', 'Charlie', 'city', 'Beijing'));

json_array

Membuat array JSON dari daftar nilai.

Sintaksis

json_array(value1, value2, value3, ...)

Parameter

ParameterDeskripsi
valueNilainya. Dapat berupa skalar, objek, atau array.

Contoh

Buat array sederhana:

SELECT json_array('apple', 'banana', 'orange');
-- Result: ["apple", "banana", "orange"]

Gunakan dalam pernyataan UPSERT:

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

Fungsi ekstraksi

Semua fungsi ekstraksi menerima kolom JSON dan ekspresi path. Tiga fungsi ekstraksi bertipe (json_extract_string, json_extract_long, json_extract_double) bersifat strongly typed — nilai pada path harus sesuai dengan tipe yang diharapkan oleh fungsi. Jika tipe tidak cocok, fungsi mengembalikan NULL atau melemparkan error. Definisikan tipe data sebelum memasukkan data JSON untuk menghindari perilaku tak terduga akibat pencampuran tipe.

json_extract

Mengekstraksi nilai dari dokumen JSON pada path yang ditentukan dan mengembalikannya dalam tipe JSON aslinya.

Sintaksis

json_extract(json_column, 'path')

Parameter

ParameterDeskripsi
json_columnKolom atau ekspresi bertipe JSON.
pathEkspresi path JSON, seperti $.field, $.array[0], atau $.nested.field.

Contoh

Ekstraksi bidang tingkat atas:

SELECT json_extract('{"name": "Alice", "age": 25}', '$.name');
-- Result: "Alice"

Ekstraksi bidang bersarang:

SELECT json_extract('{"user": {"name": "Bob", "age": 30}}', '$.user.name');
-- Result: "Bob"

Ekstraksi elemen array:

SELECT json_extract('{"skills": ["Java", "Python"]}', '$.skills[0]');
-- Result: "Java"

Ekstraksi seluruh array:

SELECT json_extract('{"skills": ["Java", "Python"]}', '$.skills');
-- Result: ["Java", "Python"]

Gunakan dalam klausa WHERE dengan perbandingan numerik:

SELECT * FROM tb WHERE json_extract(c2, '$.k3.k4') > 5;

Gunakan dalam klausa WHERE dengan perbandingan string (gunakan json_extract_string untuk type safety):

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

json_extract_string

Mengekstraksi nilai pada path yang ditentukan dan mengembalikannya sebagai VARCHAR. Jika nilai pada path bukan string, fungsi mengembalikan NULL.

Contoh

Nilai pada $.name adalah string, sehingga mengembalikan VARCHAR:

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

Nilai pada $.number adalah angka, bukan string, sehingga fungsi mengembalikan NULL:

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

json_extract_long

Mengekstraksi nilai pada path yang ditentukan dan mengembalikannya sebagai LONG. Jika nilai pada path bukan angka, Java Database Connectivity (JDBC) melemparkan error.

Contoh

Nilainya adalah integer, sehingga mengembalikan LONG:

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

Nilainya adalah bilangan titik mengambang — JDBC melemparkan error:

SELECT json_extract_long('{"id": 123456.789}', '$.id');
-- Throws an error

Nilainya adalah string numerik — JDBC melemparkan error:

SELECT json_extract_long('{"id": "123456.789"}', '$.id');
-- Throws an error

json_extract_double

Mengekstraksi nilai pada path yang ditentukan dan mengembalikannya sebagai Double. Jika nilai pada path bukan bilangan titik mengambang, JDBC melemparkan error.

Contoh

Nilainya adalah bilangan titik mengambang, sehingga mengembalikan Double:

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

Nilainya adalah integer — fungsi mengembalikannya sebagai Double:

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

Nilainya adalah string numerik — JDBC melemparkan error:

SELECT json_extract_double('{"id": "123456.789"}', '$.id');
-- Throws an error

Fungsi Pemeriksaan Penampungan

json_contains

Mengembalikan 1 jika target_json berisi semua elemen dalam candidate_json, dan 0 jika tidak. Secara opsional, tentukan path untuk memeriksa keberadaan pada lokasi tertentu dalam dokumen.

Mengembalikan NULL jika path yang ditentukan tidak ada atau jika ada parameter yang bernilai NULL.

Sintaksis

json_contains(target_json, candidate_json[, path])

Parameter

ParameterWajibDeskripsi
target_jsonYaDokumen JSON yang akan dicari.
candidate_jsonYaDokumen JSON yang akan diperiksa. Harus berupa string JSON yang valid.
pathTidakPath untuk diperiksa dalam target_json. Default-nya adalah $ (akar).

Cara memformat `candidate_json`

candidate_json harus berupa string JSON yang valid yang merepresentasikan elemen yang akan diperiksa:

Apa yang diperiksacandidate_json nilai
Angka 10'10'
String "10"'"10"'
Daftar angka'[1,2,3]'
Daftar string'["10","abc","key"]'

Klasifikasi tipe JSON

  • Skalar: String, Angka (Integer/Double), Boolean, Null

  • Tipe kompleks: Array, Objek

Aturan Pembatasan

  • Skalar hanya dapat berisi skalar lain, bukan array.

  • Array dapat berisi elemen (skalar) atau subset array.

Contoh

Persiapkan tabel contoh yang digunakan dalam kueri berikut:

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"]}');

Bentuk dua parameter memeriksa seluruh dokumen (path akar $). Ini menemukan baris di mana dokumen tingkat atas adalah array yang berisi "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#"]               |
+------+------------------------------+

Bentuk tiga parameter memeriksa path tertentu. Ini menemukan baris di mana $.skills adalah array yang berisi "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_contains mengharuskan semua elemen candidate_json hadir. Kueri ini tidak menemukan baris karena tidak ada array $.skills yang berisi kedua "Java" dan "Go":

SELECT id, data FROM test_table WHERE json_contains(data, '["Java","Go"]', '$.skills') AND id > 0 AND id < 10;
-- Empty set

Menggunakan skalar "Java" sebagai kandidat cocok dengan array yang berisi "Java" dan skalar yang sama dengan "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"}             |
+------+--------------------------------+

Periksa apakah objek berisi pasangan kunci-nilai:

SELECT json_contains('{"a": 1, "b": 2}', '{"a": 1}');
-- Result: 1

Periksa apakah path tertentu berisi nilai tertentu:

SELECT json_contains('{"a": 1, "b": 2}', '1', '$.a');
-- Result: 1

SELECT json_contains('{"a": 1, "b": 2}', '1', '$.b');
-- Result: 0

json_contains_any

Mengembalikan 1 jika target_json berisi setidaknya satu elemen dari candidate_json. Menggunakan sintaksis dan parameter yang sama seperti json_contains.

Contoh

Tanpa path, memeriksa dokumen akar. Dokumen tingkat atas adalah objek, bukan array yang secara langsung berisi "Java" atau "Go":

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

Dengan path, memeriksa $.skills. Array pada $.skills berisi "Java", yang cocok dengan salah satu elemen kandidat:

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

Bentuk dua parameter menemukan baris di mana dokumen tingkat atas adalah array dengan elemen apa pun dari ["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#"]               |
+------+------------------------------+

Bentuk tiga parameter menemukan baris di mana $.skills berisi elemen apa pun dari daftar kandidat:

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

Periksa apakah path tertentu berisi nilai apa pun dari array kandidat:

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

Memahami keberadaan skalar vs. array pada path

Pertimbangkan json_contains_any(data, '["Java"]', '$.technical_skills'). Perilakunya bergantung pada tipe JSON pada $.technical_skills:

  • Jika nilainya adalah {"technical_skills": "Java"} (string skalar), fungsi mengembalikan false. Subset dari skalar tidak bisa berupa daftar.

  • Jika nilainya adalah {"technical_skills": ["Java"]} atau {"technical_skills": ["Java", "Go"]} (array), fungsi mengembalikan true.

Pertimbangkan json_contains_any(data, '"Java"', '$.technical_skills'). Menggunakan kandidat skalar:

  • Jika nilainya adalah {"technical_skills": "Java"} (string skalar yang sama dengan "Java"), fungsi mengembalikan true.

  • Jika nilainya adalah {"technical_skills": ["Java"]} atau {"technical_skills": ["Java", "Go"]} (array yang berisi "Java"), fungsi mengembalikan true.

Fungsi pembaruan

json_set

Menyisipkan atau memperbarui nilai pada path yang ditentukan. Jika path sudah ada, nilai diperbarui. Jika path belum ada, nilai disisipkan. Jika kolom JSON bernilai NULL, hasilnya adalah NULL — objek baru tidak dibuat.

Setara dengan json_insert + json_replace.

Sintaksis

json_set(json_column, 'path', new_value)

Contoh

Perbarui bidang yang sudah ada:

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;
-- Result: {"name": "Charlie", "age": 31}

Sisipkan bidang baru:

UPDATE test_table SET data = json_set(data, '$.department', 'Engineering') WHERE id = 3;
-- Result: {"name": "Charlie", "age": 31, "department": "Engineering"}

Jika kolom JSON bernilai NULL, hasilnya tetap NULL:

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

json_insert

Menyisipkan nilai pada path yang ditentukan hanya jika path tersebut belum ada. Jika path sudah ada, fungsi tidak melakukan apa-apa.

json_insert tidak menimpa nilai yang sudah ada. Upaya menyisipkan ke bidang yang sudah ada diam-diam tidak berpengaruh — nilai asli dipertahankan.

Sintaksis

json_insert(json_column, 'path', new_value)

Contoh

Sisipkan bidang baru:

UPSERT INTO test_table (id, data) VALUES (5, '{"name": "Eve"}');
UPDATE test_table SET data = json_insert(data, '$.age', 28) WHERE id = 5;
-- Result: {"name": "Eve", "age": 28}

Mencoba menyisipkan ke bidang yang sudah ada tidak berpengaruh — bidang name tetap tidak berubah:

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

json_replace

Memperbarui nilai pada path yang ditentukan hanya jika path tersebut sudah ada. Jika path belum ada, fungsi tidak melakukan apa-apa.

Sintaksis

json_replace(json_column, 'path', new_value)

Contoh

Perbarui bidang yang sudah ada:

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;
-- Result: {"name": "Frank", "age": 36}

Mencoba memperbarui bidang yang tidak ada tidak berpengaruh — bidang city tidak ditambahkan:

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

json_remove

Menghapus nilai pada path yang ditentukan dan mengembalikan dokumen yang telah dimodifikasi. Jika path tidak ada, operasi berhasil tanpa error.

Sintaksis

json_remove(json_column, 'path')

Contoh

Hapus bidang:

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;
-- Result: {"name": "Grace"}

Menghapus bidang yang tidak ada tidak berpengaruh dan mengembalikan dokumen tanpa perubahan:

UPDATE test_table SET data = json_remove(data, '$.nonexistent') WHERE id = 7;
-- Result: {"name": "Grace"}

json_upsert

Menyisipkan atau memperbarui nilai pada path yang ditentukan. Berperilaku seperti json_set, dengan satu perbedaan utama: jika kolom JSON bernilai NULL, json_upsert membuat objek JSON baru alih-alih mengembalikan NULL.

Sintaksis

json_upsert(json_column, 'path', new_value)

Contoh

Ketika kolom JSON bernilai NULL, json_upsert membuat objek baru:

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;
-- Result: {"name": "Alice"}

Perbarui bidang yang sudah ada:

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;
-- Result: {"name": "Bob", "age": 26}

Sisipkan bidang baru:

UPDATE test_table SET data = json_upsert(data, '$.city', 'Beijing') WHERE id = 2;
-- Result: {"name": "Bob", "age": 26, "city": "Beijing"}

Perbandingan fungsi

Fungsi pemeriksaan keterkandungan

FungsiPerilaku
json_containsSetiap elemen dalam candidate_json harus ada dalam target_json. (candidate_json adalah subset dari target_json.)
json_contains_anySetidaknya satu elemen dalam candidate_json harus ada dalam target_json.

Fungsi pembaruan

FungsiKolom NULLPath adaPath tidak adaGunakan saat
json_setTetap NULLPembaruanMenyisipkanKolom diketahui tidak NULL. Sesuai dengan semantik MySQL.
json_upsertMembuat {path: value}MemperbaruiMenyisipkanPembaruan tujuan umum, termasuk saat kolom mungkin NULL.
json_insertTetap NULLTidak ada aksiPenyisipanMenambahkan bidang baru tanpa memodifikasi nilai yang sudah ada.
json_replaceTetap NULLMemperbaruiTidak ada aksiMemperbarui bidang yang sudah ada tanpa menyisipkan yang baru.
json_removeTetap NULLMenghapusTidak ada aksiMenghapus bidang.

Indeks berbasis fungsi

Buat indeks berbasis fungsi untuk mempercepat kueri pada path JSON tertentu dalam tabel lebar.

Sintaksis

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

Parameter

ParameterDeskripsi
index_nameNama tabel indeks.
table_nameNama tabel lebar.
json_extract_typeFungsi ekstraksi yang mendefinisikan path yang diindeks. Fungsi yang didukung: json_extract_string, json_extract_long, json_extract_double. Jika tipe data nilai yang diekstraksi tidak sesuai dengan tipe kembalian fungsi, tidak ada indeks sekunder yang dibuat untuk baris tersebut.
columnNama kolom JSON.
json_pathPath yang akan diindeks dalam kolom JSON.
ASYNCMembangun indeks secara asinkron. Tanpa ASYNC, indeks dibangun secara sinkron.

Fungsi yang didukung

Fungsi berikut mendukung pembuatan indeks berbasis fungsi:

  • json_extract_string(json_column, 'path') — mengindeks nilai string

  • json_extract_long(json_column, 'path') — mengindeks nilai integer panjang

  • json_extract_double(json_column, 'path') — mengindeks nilai titik mengambang

  • json_contains(json_column, 'value', 'path') — mengindeks pemeriksaan keberadaan; parameter value dan path harus berupa nilai tetap (statis)

Contoh

Buat indeks untuk mempercepat kueri json_contains pada $.roles:

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

Buat indeks pada bidang string di $.address.city:

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

Buat indeks pada bidang string tanpa menyertakan kolom tambahan:

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

Buat indeks pada bidang numerik di $.age:

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

Verifikasi bahwa indeks telah dibuat:

SHOW INDEX FROM test_table;

Untuk dukungan indeks pencarian JSON, lihat Gunakan indeks pencarian untuk tipe JSON Lindorm.

Batasan

  • Selalu gunakan sintaksis path JSON yang valid. Error illegal json path terjadi jika ekspresi path tidak valid. Untuk detail sintaksis path, lihat definisi JsonPath MySQL.

  • Operasi JSON kompleks dapat memiliki overhead performa yang signifikan. Buat indeks berbasis fungsi untuk path yang sering dikueri.

Pemecahan masalah

ErrorPenyebabPerbaikan
illegal json pathEkspresi path tidak sesuai sintaksis path JSON yang valid.Periksa sintaksis path terhadap definisi JsonPath MySQL.
json_contain candidate is not a valid valueParameter candidate bukan string JSON yang valid.Pastikan nilai kandidat diformat dengan benar sebagai string JSON.
This query may be a full table scan and thus may have unpredictable performanceKueri tidak dapat menggunakan indeks dan memindai seluruh tabel.Buat indeks berbasis fungsi untuk path yang dikueri, atau tambahkan klausa LIMIT untuk mengurangi set hasil.

Praktik terbaik

Pilih fungsi pembaruan yang tepat. Gunakan json_upsert saat kolom JSON mungkin NULL atau saat Anda membutuhkan perilaku sisip-atau-perbarui tujuan umum. Gunakan json_set saat kolom diketahui tidak NULL dan Anda menginginkan semantik yang kompatibel dengan MySQL.

Indeks path yang sering dikueri. Buat indeks berbasis fungsi pada path JSON yang muncul dalam klausa WHERE atau kondisi json_contains. Hal ini menghindari pemindaian tabel penuh dan secara signifikan meningkatkan performa kueri.

Gunakan fungsi ekstraksi bertipe untuk keamanan tipe. Gunakan json_extract_string, json_extract_long, dan json_extract_double alih-alih json_extract saat Anda membutuhkan tipe kembalian tertentu. Definisikan tipe data secara konsisten sebelum memasukkan data JSON — mencampur angka dan string numerik (misalnya angka 10 dan string "10") menyebabkan perilaku ambigu dan hasil kueri yang tidak terduga.