sql >> Databasteknik >  >> RDS >> PostgreSQL

LIKE-fråga på element i platt jsonb-array

SELECT *
FROM   posts p
WHERE  EXISTS (
   SELECT FROM jsonb_array_elements_text(p.tags) tag
   WHERE  tag LIKE '%TAG%'
   );

Relaterat, med förklaring:

  • Sök i en JSON-array efter ett objekt som innehåller ett värde som matchar ett mönster

Eller enklare med @? operatör sedan Postgres 12 implementerade 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")';

Operatören @? är bara ett omslag runt funktionen jsonb_path_exists() . Så detta är likvärdigt:

...
WHERE  jsonb_path_exists(tags, '$[*] ? (@ like_regex "TAG")');

Inte heller har indexstöd. (Kan läggas till för @? operatör senare, men inte där på sidan 13 ännu). Så dessa frågor är långsamma för stora bord. En normaliserad design, som Laurenz redan föreslagit skulle vara överlägsen - med ett trigramindex:

  • PostgreSQL LIKE frågeprestandavariationer

För bara prefixmatchning (LIKE 'TAG%' , inget inledande jokertecken), kan du få det att fungera med ett fulltextindex :

CREATE INDEX posts_tags_fts_gin_idx ON posts USING GIN (to_tsvector('simple', tags));

Och en matchande fråga:

SELECT *
FROM   posts p
WHERE  to_tsvector('simple', tags)  @@ 'TAG:*'::tsquery

Eller använd english ordbok istället för simple (eller vad som helst som passar ditt fall) om du vill ha härkomst för naturligt engelska språk.

to_tsvector(json(b)) kräver Postgres 10 eller senare.

Relaterat:

  • Få partiell matchning från GIN-indexerad TSVECTOR-kolumn
  • Mönstermatchning med LIKE, SIMILAR TO eller reguljära uttryck i PostgreSQL



  1. Välj Data via en tabellvärderad funktion i SQL Server

  2. MySQL-resultat som kommaseparerad lista

  3. Android ListView:hur undviker man databasfråga i bindView()? Behöver hämta en till många relationsdata

  4. Är cirkulära referenser godtagbara i databasen?