SELECT *
FROM posts p
WHERE EXISTS (
SELECT FROM jsonb_array_elements_text(p.tags) tag
WHERE tag LIKE '%TAG%'
);
Související s vysvětlením:
- Vyhledejte v poli JSON objekt obsahující hodnotu odpovídající vzoru
Nebo jednodušeji pomocí @?
operátor od doby, kdy Postgres 12 implementoval 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")';
Operátor @?
je jen obal kolem funkce jsonb_path_exists()
. Takže toto je ekvivalentní:
...
WHERE jsonb_path_exists(tags, '$[*] ? (@ like_regex "TAG")');
Ani jeden nemá podporu indexu. (Lze přidat pro @?
operátor později, ale zatím tam na str. 13 není). Takže tyto dotazy jsou pomalé pro velké tabulky. Normalizovaný design, jak už navrhl Laurenz, by byl lepší – s trigramovým indexem:
- Varianty výkonu dotazů PostgreSQL LIKE
Pouze pro párování předpon (LIKE 'TAG%'
, žádný zástupný znak na začátku), můžete to zprovoznit pomocí úplného textového indexu :
CREATE INDEX posts_tags_fts_gin_idx ON posts USING GIN (to_tsvector('simple', tags));
A odpovídající dotaz:
SELECT *
FROM posts p
WHERE to_tsvector('simple', tags) @@ 'TAG:*'::tsquery
Nebo použijte english
slovník namísto simple
(nebo cokoli, co se hodí pro váš případ), pokud chcete vycházet z přirozené angličtiny.
to_tsvector(json(b))
vyžaduje Postgres 10 nebo později.
Související:
- Získejte částečnou shodu ze sloupce TSVECTOR indexovaného GIN
- Shoda vzoru s LIKE, SIMILAR TO nebo regulárními výrazy v PostgreSQL