全部产品
Search
文档中心

Hologres:Tipe data JSON dan JSONB

更新时间:Jul 12, 2025

Topik ini menjelaskan sintaks yang didukung oleh tipe data JSON dan JSONB serta cara menggunakan tipe data tersebut.

Ikhtisar Tipe Data JSON dan JSONB

Dalam beberapa tahun terakhir, meningkatnya popularitas aplikasi seluler telah mendorong kebutuhan untuk skenario seperti pelacakan aplikasi dan komputasi tag pengguna. Untuk memenuhi kebutuhan ini, semakin banyak sistem data besar mulai menggunakan format semi-terstruktur untuk menyimpan data terkait agar pengembangan dan pemrosesan lebih fleksibel. JSON dan JSONB adalah tipe data semi-terstruktur yang umum digunakan. Berikut ini menjelaskan perbedaan antara tipe data JSON dan JSONB:

  • Data tipe JSON disimpan dalam bentuk teks, sedangkan data tipe JSONB disimpan dalam format biner.

  • Penulisan data tipe JSON relatif cepat, tetapi pembacaan memerlukan waktu lebih lama karena setiap kali data di-query, fungsi pemrosesan harus menguraikan ulang data tersebut. Sebaliknya, data tipe JSONB dapat dibaca dengan cepat, namun penulisannya memerlukan waktu lebih lama karena konversi tambahan diperlukan saat menulis data ke Hologres. Query data JSONB lebih efisien karena tidak memerlukan penguraian ulang.

  • Tipe data JSON menyimpan salinan tepat dari teks input, termasuk spasi, kunci objek duplikat, dan urutan kunci objek. Jika suatu objek JSON berisi kunci yang sama lebih dari satu kali, semua pasangan kunci-nilai dipertahankan. Sementara itu, tipe data JSONB menghapus spasi yang tidak diperlukan, kunci objek duplikat, dan urutan kunci objek saat teks input diuraikan. Jika kunci objek duplikat ditentukan, hanya nilai terakhir yang dipertahankan.

Perbedaan utama antara kedua tipe data ini terletak pada efisiensi pemrosesan data.

  • Tipe data JSON menyimpan salinan tepat dari teks input, sehingga setiap eksekusi memerlukan penguraian ulang. Karakter seperti spasi yang tidak signifikan mungkin ada untuk mematuhi kendala semantik teks input. Jika suatu objek JSON berisi kunci yang sama lebih dari satu kali, semua pasangan kunci-nilai dipertahankan, tetapi fungsi pemrosesan menganggap nilai terakhir sebagai nilai valid.

  • Data tipe JSONB disimpan dalam format biner yang sudah terurai. Meskipun proses penulisan memerlukan waktu lebih lama karena konversi tambahan, query data lebih cepat karena tidak memerlukan penguraian ulang. Spasi, urutan kunci objek, dan kunci objek duplikat dihilangkan dalam data JSONB. Jika kunci objek duplikat ditentukan, hanya nilai terakhir yang dipertahankan.

Batasan

Hologres mendukung tipe data JSON dan JSONB. Saat menggunakan tipe data ini, perhatikan batasan berikut:

  • Hanya Hologres V0.9 dan versi lebih baru yang mendukung tipe data JSON. Jika versi instance Hologres Anda lebih lama dari V0.9, tingkatkan instance Hologres secara manual melalui konsol Hologres atau bergabunglah dengan grup DingTalk Hologres untuk mengajukan peningkatan instance. Untuk informasi lebih lanjut tentang cara menaikkan versi instance Hologres secara manual, lihat Peningkatan Instance. Untuk informasi lebih lanjut tentang cara bergabung dengan grup DingTalk Hologres, lihat Dapatkan dukungan online untuk Hologres.

  • Hanya Hologres V1.1 dan versi lebih baru yang mendukung indeks GIN untuk bidang tipe data JSONB.

  • Hanya Hologres V1.3 dan versi lebih baru yang mendukung penyimpanan berorientasi kolom untuk tipe data JSONB. Penyimpanan berorientasi kolom hanya dapat digunakan untuk tabel berorientasi kolom dan memerlukan minimal 1.000 catatan data.

  • Hologres tidak mendukung fungsi JSON tertentu berikut: json_each, jsonb_each, json_each_text, jsonb_each_text, json_extract_path, jsonb_extract_path, dan jsonb_to_record.

    Jika Anda ingin menggunakan fungsi jsonb_extract_path dan json_extract_path, jalankan pernyataan berikut:

    • SELECT json_extract_path(
                              '{"key":{"key1":"key1","key2":"key2"}}'::json
                              , 'key'
                              , 'key1'
      );
      -- Pernyataan setara dengan fungsi json_extract_path:
      SELECT
          '{"key":{"key1":"key1","key2":"key2"}}'::json #> '{"key","key1"}';
    • SELECT jsonb_extract_path(
                  '{"key":{"key1":"key1","key2":"key2"}}'::jsonb
                  , 'key'
                  , 'key1'
      );
      -- Pernyataan setara dengan fungsi jsonb_extract_path:
      SELECT
          '{"key":{"key1":"key1","key2":"key2"}}'::jsonb #> '{"key","key1"}';                                    

Operator yang Didukung oleh Data Tipe JSON dan JSONB

Operator yang Umum Digunakan

Tabel berikut menjelaskan operator umum yang didukung oleh data tipe JSON dan JSONB.

Operator

Tipe Operand Kanan

Deskripsi

Contoh

Hasil Eksekusi

->

int

Mendapatkan elemen array JSON dengan indeks dimulai dari nol. Bilangan bulat negatif menunjukkan bahwa elemen dihitung mundur dari akhir.

select '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2

{"c":"baz"}

->

text

Mendapatkan bidang objek JSON berdasarkan kunci.

select '{"a": {"b":"foo"}}'::json->'a'

{"b":"foo"}

->>

int

Mendapatkan elemen array JSON sebagai teks.

select '[1,2,3]'::json->>2

3

->>

text

Mendapatkan bidang objek JSON sebagai teks.

select '{"a":1,"b":2}'::json->>'b'

2

#>

text[]

Mendapatkan objek JSON dari jalur yang ditentukan.

select '{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}'

{"c":"foo"}

#>>

text[]

Mendapatkan objek JSON sebagai teks dari jalur yang ditentukan.

select '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'

3

Operator Lain yang Didukung

Tabel berikut menjelaskan operator tambahan yang didukung oleh data tipe JSON dan JSONB. Operator tambahan digunakan untuk memenuhi kebutuhan pengembangan bisnis yang berbeda.

Operator

Tipe Operand Kanan

Deskripsi

Contoh

Hasil Eksekusi

@>

jsonb

Menentukan apakah nilai JSON kiri berisi jalur JSON atau nilai kanan.

select '{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb

true

<@

jsonb

Menentukan apakah jalur JSON atau nilai kiri terkandung dalam nilai JSON kanan.

select '{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb

true

?

text

Menentukan apakah string kunci atau elemen ada dalam nilai JSON.

select '{"a":1, "b":2}'::jsonb ? 'b'

true

?|

text[]

Menentukan apakah string kunci atau elemen dalam string array ada dalam nilai JSON.

select '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c']

true

?&

text[]

Menentukan apakah semua string array ada dalam nilai JSON.

select '["a", "b"]'::jsonb ?& array['a', 'b']

true

||

jsonb

Menggabungkan dua nilai JSONB menjadi nilai JSONB baru.

Catatan

Operator || menggabungkan elemen operasi dalam setiap nilai JSON, tetapi tidak melakukan operasi rekursif. Misalnya, jika dua operand adalah objek dengan nama bidang kunci yang sama, operator ini mengembalikan nilai di mana nilai bidang adalah nilai dari operand kanan.

select '["a", "b"]'::jsonb || '["c", "d"]'::jsonb

["a", "b", "c", "d"]

-

text

Menghapus kunci atau nilai dari operand kiri. Kunci atau nilai dicocokkan berdasarkan nilai kunci.

select '{"a": "b"}'::jsonb - 'a'

{}

-

text[]

Menghapus beberapa kunci atau nilai dari operand kiri. Kunci atau nilai dicocokkan berdasarkan nilai kunci.

select '{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[]

{}

-

integer

Menghapus elemen array yang berada di posisi yang ditentukan. Bilangan bulat negatif menunjukkan bahwa elemen dihitung mundur dari akhir. Kesalahan dikembalikan jika data JSON tidak disimpan sebagai array.

select '["a", "b"]'::jsonb - 1

["a"]

#-

text[]

Menghapus elemen dengan jalur yang ditentukan. Untuk array JSON, bilangan bulat negatif menunjukkan bahwa elemen dihitung mundur dari akhir.

select '["a", {"b":1}]'::jsonb #- '{1,b}'

["a", {}]

Fungsi yang Mendukung Tipe Data JSON dan JSON

Fungsi Pemrosesan

Tabel berikut menjelaskan fungsi yang digunakan untuk memproses nilai JSON dan JSONB.

Fungsi

Tipe Nilai Kembali

Deskripsi

Contoh

Hasil Eksekusi

json_array_length(json)

int

Mengembalikan jumlah elemen dalam array JSON paling luar.

select json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')

5

jsonb_array_length(jsonb)

json_object_keys(json)

setof text

Mengembalikan satu set kunci dalam objek JSON paling luar.

select json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}')

json_object_keys
------------------
 f1
 f2

jsonb_object_keys(jsonb)

json_populate_record(base anyelement, from_json json)

anyelement

Mengembangkan objek dalam parameter from_json menjadi baris dengan kolom yang sesuai dengan tipe rekaman yang didefinisikan oleh parameter base.

begin;
create table 
myrowtype( a text, b text, c text);commit;
select * from json_populate_record(null::myrowtype, '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}}')
 a |   b       |      c
---+-----------+-------------
 1 | ["2", "a b"] | {"d": 4, "e": "a b c"}

jsonb_populate_record(base anyelement, from_json jsonb)

json_populate_recordset(base anyelement, from_json json)

setof anyelement

Mengembangkan array paling luar dari objek dalam parameter from_json menjadi satu set baris dengan kolom yang sesuai dengan tipe rekaman yang didefinisikan oleh parameter base.

begin;
create table 
myrowtype(a text,b text);
commit;
select * from json_populate_recordset(null::myrowtype, '[{"a":1,"b":2},{"a":3,"b":4}]')
 a | b
---+---
 1 | 2
 3 | 4

jsonb_populate_recordset(base anyelement, from_json jsonb)

json_array_elements(json)

setof json

Mengembangkan array JSON menjadi satu set nilai JSON.

select * from json_array_elements('[1,true, [2,false]]')

   value
-----------
 1
 true
 [2,false]

jsonb_array_elements(jsonb)

setof jsonb

json_array_elements_text(json)

setof text

Mengembangkan array JSON menjadi satu set nilai teks.

select * from json_array_elements_text('["foo", "bar"]')

 value
-----------
 foo
 bar

jsonb_array_elements_text(jsonb)

json_typeof(json)

text

Mengembalikan tipe data dari nilai JSON paling luar sebagai string teks. Tipe data yang mungkin termasuk OBJECT, ARRAY, STRING, NUMBER, BOOLEAN, dan NULL.

select json_typeof('-123.4')

number

jsonb_typeof(jsonb)

json_strip_nulls(from_json json)

json

Mengembalikan objek dalam parameter from_json. Bidang objek yang memiliki nilai null dihilangkan. Nilai null lainnya dipertahankan.

select json_strip_nulls('[{"f1":1,"f2":null},2,null,3]')

[{"f1":1},2,null,3]

jsonb_strip_nulls(from_json jsonb)

jsonb

jsonb_set(target jsonb, path text[], new_value jsonb[,create_missing boolean])

jsonb

Mengembalikan objek dalam parameter target. Node yang ditentukan oleh parameter path diganti dengan nilai dari parameter new_value. Jika nilai parameter create_missing adalah true dan item yang ditentukan oleh parameter path tidak ada, nilai dari parameter new_value dimasukkan. Nilai default dari parameter create_missing adalah true. Sesuai dengan persyaratan operator berbasis jalur, bilangan bulat negatif dalam nilai parameter path menunjukkan bahwa elemen dihitung mundur dari akhir array JSON.

select jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false);

[{"f1":[2,3,4],"f2":null},2,null,3]

select jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}','[2,3,4]')

[{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]

jsonb_insert(target jsonb, path text[], new_value jsonb, [insert_after boolean])

jsonb

Mengembalikan objek dalam parameter target dengan nilai dari parameter new_value disisipkan. Node yang ditentukan oleh parameter path dapat berada dalam array JSONB. Dalam hal ini, jika nilai parameter insert_after adalah false, yang merupakan nilai default, nilai dari parameter new_value disisipkan sebelum nilai dari parameter target. Sebaliknya, nilai dari parameter new_value disisipkan setelah nilai dari parameter target. Node yang ditentukan oleh parameter path dapat berada dalam objek JSONB. Dalam hal ini, nilai dari parameter new_value hanya disisipkan jika nilai dari parameter target tidak ada. Sesuai dengan persyaratan operator berbasis jalur, bilangan bulat negatif dalam nilai parameter path menunjukkan bahwa elemen dihitung mundur dari akhir array JSON.

select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"')

{"a": [0, "new_value", 1, 2]}

select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true)

{"a": [0, 1, "new_value", 2]}

jsonb_pretty(from_json jsonb)

text

Mengembalikan objek dalam parameter from_json sebagai teks JSON yang berindentasi.

select jsonb_pretty('[{"f1":1,"f2":null},2,null,3]')

[
    {
        "f1": 1,
        "f2": null
    },
    2,
    null,
    3
]

jsonb_agg

jsonb

Mengumpulkan nilai, termasuk nilai null, ke dalam array JSON.

DROP TABLE IF EXISTS t;

CREATE TABLE t (
    k int PRIMARY KEY,
    class int NOT NULL,
    v text NOT NULL
);

INSERT INTO t (k, class, v)
SELECT
    (1 + s.v),
    CASE (s.v) < 3
    WHEN TRUE THEN
        1
    ELSE
        2
    END,
    chr(97 + s.v)
FROM
    generate_series(0, 5) AS s (v);

SELECT
    class,
    jsonb_agg(v ORDER BY v DESC) FILTER (WHERE v <> 'b') AS "jsonb_agg",
    jsonb_object_agg(v, k ORDER BY v DESC) FILTER (WHERE v <> 'e') AS "jsonb_object_agg(v, k)"
FROM
    t
GROUP BY
    class;
 class |    jsonb_agg    |  jsonb_object_agg(v, k)
-------+-----------------+--------------------------
     1 | ["c", "a"]      | {"a": 1, "b": 2, "c": 3}
     2 | ["f", "e", "d"] | {"d": 4, "f": 6}

jsonb_object_agg

jsonb

Mengumpulkan pasangan kunci-nilai ke dalam objek JSON. Nilai dapat kosong, tetapi kunci tidak boleh kosong.

DROP TABLE IF EXISTS t;

CREATE TABLE t (
    k int PRIMARY KEY,
    class int NOT NULL,
    v text NOT NULL
);

INSERT INTO t (k, class, v)
SELECT
    (1 + s.v),
    CASE (s.v) < 3
    WHEN TRUE THEN
        1
    ELSE
        2
    END,
    chr(97 + s.v)
FROM
    generate_series(0, 5) AS s (v);

SELECT
    class,
    jsonb_agg(v ORDER BY v DESC) FILTER (WHERE v <> 'b') AS "jsonb_agg",
    jsonb_object_agg(v, k ORDER BY v DESC) FILTER (WHERE v <> 'e') AS "jsonb_object_agg(v, k)"
FROM
    t
GROUP BY
    class;
 class |    jsonb_agg    |  jsonb_object_agg(v, k)
-------+-----------------+--------------------------
     1 | ["c", "a"]      | {"a": 1, "b": 2, "c": 3}
     2 | ["f", "e", "d"] | {"d": 4, "f": 6}

is_valid_json

BOOLEAN

Memvalidasi string JSON. Nilai Boolean true (t) dikembalikan jika string input adalah string JSON yang valid. Jika tidak, nilai Boolean false (f) dikembalikan.

Catatan
  • Hanya Hologres V1.3.12 dan versi lebih baru yang mendukung fungsi ini.

  • Tipe data ARRAY juga merupakan tipe data JSON. Data tipe ARRAY dapat ditulis ke kolom JSON atau JSONB.

DROP TABLE IF EXISTS test_json;

CREATE TABLE test_json (
    id int,
    json_strings text
);

INSERT INTO test_json
    VALUES (1, '{"a":2}'), (2, '{"a":{"b":{"c":1}}}'), (3, '{"a": [1,2,"b"]}');

INSERT INTO test_json
    VALUES (4, '{{}}'), (5, '{1:"a"}'), (6, '[1,2,3]');

SELECT
    id,
    json_strings,
    is_valid_json (json_strings)
FROM
    test_json
ORDER BY
    id;
id | json_strings        | is_valid_json
---+---------------------+--------------
 0 | {"a":2}             | true
 2 | {"a":{"b":{"c":1}}} | true
 4 | {"a": [1,2,"b"]}    | true
 6 | {{}}                | false
 8 | {1:"a"}             | false
10 | [1,2,3]             | true

Fungsi Penguraian

Fungsi

Deskripsi

Contoh

Hasil Eksekusi

try_cast_to_jsonb(text)

Mengonversi data tipe TEXT menjadi data tipe JSONB. Jika data tidak sesuai dengan format JSONB, nilai null dikembalikan.

Catatan

Hanya Hologres V2.0.24 dan versi lebih baru yang mendukung fungsi ini.

  • select try_cast_to_jsonb('{"key": 1}');

  • select try_cast_to_jsonb('{"key": 1');

  • {"key": 1}

  • NULL

to_json(anyelement)

Mengembalikan nilai sebagai objek JSON yang valid. Array dan komposit diubah secara rekursif menjadi array dan objek. Untuk nilai yang bukan array atau komposit, jika fungsi cast disediakan, fungsi cast dipanggil untuk mengonversi nilai input menjadi objek JSON. Jika tidak, nilai skalar dihasilkan. Jika nilai skalar bukan tipe data NUMBER, BOOLEAN, atau NULL, nilai skalar direpresentasikan oleh teks JSON. Dalam hal ini, nilai skalar adalah string JSON yang valid.

select to_json('Fred said "Hi."'::text)

"Fred said \"Hi.\""

to_jsonb(anyelement)

array_to_json(anyarray [, pretty_bool])

Mengembalikan array sebagai array JSON. Jika Anda memasukkan array multidimensi, array dari array JSON dikembalikan. Jika nilai parameter pretty_bool adalah true, baris baru ditambahkan di antara elemen-elemen dimensi-1.

select array_to_json('{{1,5},{99,100}}'::int[])

[[1,5],[99,100]]

json_build_array(VARIADIC "any")

Membangun array JSON yang mungkin berisi data heterogen berdasarkan daftar argumen variabel.

select json_build_array(1,2,'3',4,5)

[1, 2, "3", 4, 5]

jsonb_build_array(VARIADIC "any")

json_build_object(VARIADIC "any")

Membangun objek JSON berdasarkan daftar argumen variabel. Daftar argumen terdiri dari kunci dan nilai yang bergantian.

select json_build_object('foo',1,'bar',2)

{"foo": 1, "bar": 2}

jsonb_build_object(VARIADIC "any")

json_object(text[])

Membangun objek JSON berdasarkan array teks. Array tersebut dapat berupa array satu dimensi yang berisi anggota genap. Anggota-anggota diambil sebagai pasangan kunci-nilai bergantian. Array tersebut juga dapat berupa array dua dimensi. Setiap array dalam memiliki dua elemen, yang diambil sebagai pasangan kunci-nilai.

select json_object('{a, 1, b, "def", c, 3.5}');

{"a": "1", "b": "def", "c": "3.5"}

jsonb_object(text[])

select jsonb_object('{a, 1, b, "def", c, 3.5}');

{"a": "1", "b": "def", "c": "3.5"}

json_object(keys text[], values text[])

Mendapatkan pasangan kunci-nilai berdasarkan dua array terpisah. Dalam aspek lain, pasangan kunci-nilai tersebut dalam format yang sama dengan argumen tunggal.

select json_object('{a, b}', '{1,2}')

{"a": "1", "b": "2"}

jsonb_object(keys text[], values text[])

Pengindeksan Bidang JSONB

Dalam Hologres V1.1 dan versi lebih baru, indeks GIN dan B-tree dapat dibuat untuk bidang tipe data JSONB untuk mempercepat query data. Anda dapat menggunakan salah satu operator berikut untuk membuat indeks GIN untuk bidang tipe data JSONB: operator default jsonb_ops dan operator jsonb_path_ops. Dalam topik ini, indeks dibuat untuk bidang tipe data JSONB. Kami merekomendasikan Anda membuat indeks untuk bidang tipe data JSONB daripada tipe data JSON.

Catatan
  • Indeks GIN JSONB tidak didukung dalam kombinasi dengan optimasi penyimpanan kolom JSONB. Mulai dari Hologres V3.0.42 dan V3.1.10, jika kedua fitur diaktifkan, indeks GIN tidak akan berfungsi.

  • Indeks GIN JSONB cocok untuk bidang JSONB yang jarang. Untuk skenario non-jarang, disarankan untuk menggunakan optimasi penyimpanan kolom JSONB.

  • Gunakan operator default jsonb_ops untuk membuat indeks.

    CREATE INDEX idx_name ON table_name USING gin (idx_col);
  • Gunakan operator jsonb_path_ops untuk membuat indeks.

    CREATE INDEX idx_name ON table_name USING gin (idx_col jsonb_path_ops);

Perbedaan antara jsonb_ops dan jsonb_path_ops adalah bahwa jsonb_ops membuat item indeks independen untuk setiap kunci dan nilai dalam data, sedangkan jsonb_path_ops hanya membuat item indeks untuk setiap nilai dalam data.

Indeks GIN dapat dibuat menggunakan operator PostgreSQL asli dan operator Hologres. Bagian berikut memberikan contohnya.

Operator Asli yang Disediakan oleh PostgreSQL

  • Gunakan operator jsonb_ops untuk membuat indeks.

    -- 1. Buat tabel.
    BEGIN;
    DROP TABLE IF EXISTS json_table;
    
    CREATE TABLE IF NOT EXISTS json_table
    (
        id INT
        ,j jsonb
    );
    COMMIT;
    
    -- 2. Gunakan operator jsonb_ops untuk membuat indeks.
    CREATE INDEX index_json on json_table USING GIN(j);
    
    -- 3. Masukkan data ke dalam tabel.
    INSERT INTO json_table VALUES
    (1, '{"key1": 1, "key2": [1, 2], "key3": {"a": "b"}}') ,
    (1, '{"key1": 1}'),
    (2, '{"key2": [1, 2], "key3": {"a": "b"}}') ;
    
    -- 4. Query data dari tabel.
    SELECT  * FROM    json_table WHERE   j ? 'key1';
    -- Hasil berikut dikembalikan:
     id |                        j
    ----+-------------------------------------------------
      1 | {"key1": 1, "key2": [1, 2], "key3": {"a": "b"}}
      1 | {"key1": 1}
    
                        

    Jalankan pernyataan EXPLAIN untuk menanyakan rencana eksekusi. Contoh kode:

    explain SELECT  * FROM    json_table WHERE   j ? 'key1';
    
    QUERY PLAN
    Gather  (cost=0.00..0.26 rows=1000 width=12)
      ->  Local Gather  (cost=0.00..0.23 rows=1000 width=12)
            ->  Decode  (cost=0.00..0.23 rows=1000 width=12)
                  ->  Bitmap Heap Scan on json_table  (cost=0.00..0.13 rows=1000 width=12)
                        Recheck Cond: (j ? 'key1'::text)
                        ->  Bitmap Index Scan on index_json  (cost=0.00..0.00 rows=0 width=0)
                              Index Cond: (j ? 'key1'::text)
    Optimizer: HQO version 1.3.0

    Hasil sebelumnya menunjukkan bahwa rencana eksekusi berisi langkah Index Scan. Ini menunjukkan bahwa indeks digunakan selama query.

  • Gunakan operator jsonb_path_ops untuk membuat indeks.

    -- 1. Buat tabel.
    BEGIN;
    DROP TABLE IF EXISTS json_table;
    
    CREATE TABLE IF NOT EXISTS json_table
    (
        id INT
        ,j jsonb
    );
    COMMIT;
    
    -- 2. Gunakan operator jsonb_ops untuk membuat indeks.
    CREATE INDEX index_json on json_table USING GIN(j jsonb_path_ops);
    
    -- 3. Masukkan data ke dalam tabel.
    INSERT INTO json_table (
        SELECT
            i,
            ('{
                "key1": "'||i||'"
                ,"key2": "'||i%100||'"
                ,"key3": "'||i%1000 ||'"
                ,"key4": "'||i%10000||'"
                ,"key5": "'||i%100000||'"
            }')::jsonb
        FROM generate_series(1, 1000000) i
    ) ;
    
    -- 4. Query data yang berisi '{"key1": "10"}' dari tabel.
    SELECT  * FROM    json_table WHERE   j @> '{"key1": "10"}'::JSONB;
    -- Hasil berikut dikembalikan:
     id |                                   j
    ----+------------------------------------------------------------------------
     10 | {"key1": "10", "key2": "10", "key3": "10", "key4": "10", "key5": "10"}
    (1 row)
                        

    Jalankan pernyataan EXPLAIN untuk menanyakan rencana eksekusi. Contoh kode:

    explain SELECT  * FROM    json_table WHERE   j @> '{"key1": "10"}'::JSONB;
    
                                            QUERY PLAN
    -------------------------------------------------------------------------------------------
     Gather  (cost=0.00..0.26 rows=1000 width=12)
       ->  Local Gather  (cost=0.00..0.23 rows=1000 width=12)
             ->  Decode  (cost=0.00..0.23 rows=1000 width=12)
                   ->  Bitmap Heap Scan on json_table  (cost=0.00..0.13 rows=1000 width=12)
                         Recheck Cond: (j @> '{"key1": "10"}'::jsonb)
                         ->  Bitmap Index Scan on index_json  (cost=0.00..0.00 rows=0 width=0)
                               Index Cond: (j @> '{"key1": "10"}'::jsonb)
     Optimizer: HQO version 1.3.0
    (8 rows)
                        

    Hasil sebelumnya menunjukkan bahwa rencana eksekusi berisi langkah Index Scan. Ini menunjukkan bahwa indeks digunakan selama query.

Operator yang Disediakan oleh Hologres

Indeks GIN untuk bidang tipe data JSONB yang disediakan oleh PostgreSQL asli tidak selalu menghasilkan data akurat dan memerlukan pemeriksaan ulang setelah data diambil. Kinerja query mungkin tidak meningkat meskipun indeks digunakan. Hologres menyediakan operator ops_class, yang tidak memerlukan pemeriksaan ulang data. Jika tidak ditentukan, operator ops_class digunakan secara default.

Catatan

Operator ops_class mendukung indeks dengan panjang 1 hingga 127 byte. Jika indeks melebihi 127 byte, indeks akan dipotong. Oleh karena itu, bidang tipe data JSONB yang ingin Anda buat indeksnya juga akan dipotong jika panjang indeks melebihi 127 byte. Dalam hal ini, data perlu diperiksa ulang. Anda dapat menjalankan pernyataan EXPLAIN ANALYZE untuk menentukan apakah data diperiksa ulang.

Kelas operator jsonb_holo_ops sesuai dengan kelas operator jsonb_ops dan mendukung operasi penyaringan menggunakan operator berikut: ?, ?|, ?&, @>. Kelas operator jsonb_holo_path_ops sesuai dengan kelas operator jsonb_path_ops. Hanya operasi penyaringan menggunakan operator @> yang didukung.

  • Gunakan operator jsonb_holo_ops untuk membuat indeks.

    -- 1. Buat tabel.
    BEGIN ;
    DROP TABLE IF EXISTS json_table;
    CREATE TABLE IF NOT EXISTS json_table
    (
        id INT
        ,j jsonb
    );
    COMMIT ;
    
    -- 2. Gunakan operator jsonb_holo_ops untuk membuat indeks.
    CREATE INDEX index_json on json_table USING GIN(j jsonb_holo_ops);
    
    -- 3. Masukkan data ke dalam tabel.
    INSERT INTO json_table VALUES
    (1, '{"key1": 1, "key2": [1, 2], "key3": {"a": "b"}}') ,
    (1, '{"key1": 1}'),
    (2, '{"key2": [1, 2], "key3": {"a": "b"}}') ;
    
    -- 4. Query data dari tabel.
    SELECT  * FROM    json_table WHERE   j ? 'key1';
    -- Hasil berikut dikembalikan:
     id |                        j
    ----+-------------------------------------------------
      1 | {"key1": 1}
      1 | {"key1": 1, "key2": [1, 2], "key3": {"a": "b"}}
    (2 rows)
  • Gunakan operator jsonb_holo_path_ops untuk membuat indeks.

    -- 1. Buat tabel.
    BEGIN ;
    DROP TABLE IF EXISTS json_table;
    CREATE TABLE IF NOT EXISTS json_table
    (
        id INT
        ,j jsonb
    );
    
    -- 2. Gunakan operator jsonb_holo_path_ops untuk membuat indeks.
    CREATE INDEX index_json on json_table USING GIN(j jsonb_holo_path_ops);
    
    -- 3. Masukkan data ke dalam tabel.
    INSERT INTO json_table (
        SELECT
            i,
            ('{
                "key1": "'||i||'"
                ,"key2": "'||i%100||'"
                ,"key3": "'||i%1000 ||'"
                ,"key4": "'||i%10000||'"
                ,"key5": "'||i%100000||'"
            }')::jsonb
        FROM generate_series(1, 1000000) i
    ) ;
    
    -- 4. Query data yang berisi '{"key1": "10"}' dari tabel.
    SELECT  * FROM  json_table WHERE j @> '{"key1": "10"}'::JSONB ;
    -- Hasil berikut dikembalikan:
     id |                                   j
    ----+------------------------------------------------------------------------
     10 | {"key1": "10", "key2": "10", "key3": "10", "key4": "10", "key5": "10"}
    (1 row)

Contoh Impor Data: Impor Data JSONB dari Realtime Compute for Apache Flink ke Hologres secara real-time

Saat Anda mengimpor data dari Realtime Compute for Apache Flink ke Hologres, Anda harus mendefinisikan tipe data bidang ke tipe data yang didukung oleh Realtime Compute for Apache Flink dalam penyebaran SQL. Saat Anda membuat tabel internal di Hologres, Anda harus mendefinisikan tipe data bidang ke tipe data yang didukung oleh Hologres. Untuk informasi lebih lanjut tentang pemetaan tipe data antara Realtime Compute for Apache Flink dan Hologres, lihat Pemetaan tipe data antara Realtime Compute for Apache Flink dan Hologres.

Untuk mengimpor data JSON dari Realtime Compute for Apache Flink ke Hologres, definisikan VARCHAR sebagai tipe data untuk data JSON dalam tabel sumber dan tabel hasil dalam penyebaran SQL Realtime Compute for Apache Flink. Dalam tabel internal Hologres, definisikan JSONB sebagai tipe data. Contoh:

  • Buat tabel internal di Hologres dan definisikan JSONB sebagai tipe data untuk bidang message.

    BEGIN ;
    DROP TABLE IF EXISTS holo_internal_table;
    CREATE TABLE IF NOT EXISTS holo_internal_table
    (
        id BIGINT NOT NULL,
        message JSONB NOT NULL
    );
    CALL set_table_property('holo_internal_table', 'distribution_key', 'id');
    COMMIT ;
  • Dalam penyebaran SQL Realtime Compute for Apache Flink, definisikan VARCHAR sebagai tipe data untuk bidang message dalam tabel sumber dan tabel hasil. Kemudian, tulis data ke Hologres.

    CREATE TEMPORARY TABLE randomSource (
        id BIGINT,
        message VARCHAR
      )
    WITH ('connector' = 'datagen');
    
    CREATE TEMPORARY TABLE sink_holo (
        id BIGINT,
        message VARCHAR
      )
    WITH (
         'connector' = 'hologres',
        'dbname'='<yourDBname>',  -- Nama database Hologres yang ingin Anda hubungkan.
        'tablename'='<holo_internal_table>', -- Nama tabel Hologres ke mana data ditulis.
        'username'='<yourUsername>', -- ID AccessKey akun Alibaba Cloud Anda.
        'password'='<yourPassword>', -- Rahasia AccessKey akun Alibaba Cloud Anda.
        'endpoint'='<yourEndpoint>', --Titik akhir virtual private cloud (VPC) instance Hologres Anda.
      );
    
    INSERT INTO sink_holo
    SELECT 
      1,
      '{"k":"v"}'
    FROM
      randomSource;

Dukungan untuk Penyimpanan Berorientasi Kolom untuk Data Tipe JSONB

Indeks GIN digunakan untuk meningkatkan kinerja hanya pada lapisan komputasi. Dalam proses komputasi, seluruh konten JSON perlu dipindai. Hologres V1.3 dan versi lebih baru mendukung penyimpanan berorientasi kolom untuk data tipe JSONB berdasarkan optimasi pada lapisan penyimpanan. Data tipe JSONB dapat disimpan dalam kolom seperti data terstruktur, meningkatkan efisiensi kompresi data dan mempercepat query data berformat JSONB.

Untuk informasi lebih lanjut tentang penyimpanan berorientasi kolom untuk data berformat JSONB, lihat Penyimpanan Berorientasi Kolom untuk Data Berformat JSONB.