SELECT *
FROM posts p
WHERE EXISTS (
SELECT FROM jsonb_array_elements_text(p.tags) tag
WHERE tag LIKE '%TAG%'
);
Terkait, dengan penjelasan:
- Menelusuri larik JSON untuk objek yang berisi nilai yang cocok dengan pola
Atau lebih sederhana dengan @?
operator sejak Postgres 12 mengimplementasikan SQL/JSON:
SELECT *
-- optional to show the matching item:
-- , jsonb_path_query_first(tags, '$[*] ? (@ like_regex "^ tag" flag "i")')
FROM posts
WHERE tags @? '$[*] ? (@ like_regex "TAG")';
Operator @?
hanyalah pembungkus di sekitar fungsi jsonb_path_exists()
. Jadi ini setara:
...
WHERE jsonb_path_exists(tags, '$[*] ? (@ like_regex "TAG")');
Tidak memiliki dukungan indeks. (Dapat ditambahkan untuk @?
operator nanti, tetapi belum ada di hal 13). Jadi kueri itu lambat untuk tabel besar. Desain yang dinormalisasi, seperti yang disarankan Laurenz akan lebih unggul - dengan indeks trigram:
- Variasi kinerja kueri SEPERTI PostgreSQL
Hanya untuk pencocokan awalan (LIKE 'TAG%'
, tanpa karakter pengganti di depan), Anda dapat membuatnya bekerja dengan indeks teks lengkap :
CREATE INDEX posts_tags_fts_gin_idx ON posts USING GIN (to_tsvector('simple', tags));
Dan kueri yang cocok:
SELECT *
FROM posts p
WHERE to_tsvector('simple', tags) @@ 'TAG:*'::tsquery
Atau gunakan english
kamus bukannya simple
(atau apa pun yang sesuai dengan kasus Anda) jika Anda ingin menggunakan bahasa Inggris alami.
to_tsvector(json(b))
membutuhkan Postgres 10 atau lambat.
Terkait:
- Dapatkan kecocokan sebagian dari kolom TSVECTOR yang diindeks GIN
- Pencocokan pola dengan LIKE, SIMILAR TO atau ekspresi reguler di PostgreSQL