2015-04-29 14 views
5

Odnosząc się do original stackoverflow question, próbuję zastosować indeksy ginu do kluczy w obiektach tablicy w PostgreSQL 9.4, ale nie otrzymuję wyników jak podano w pierwszej odpowiedzi.Używanie indeksów w tablicy json w PostgreSQL

Czy możesz poprawić błąd?

Kroki, które obserwowałem, zostały napisane poniżej.

Część 1: Tworzenie tabeli i indeksy

CREATE TABLE tracks (id serial, artists jsonb); 
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists); 
INSERT INTO tracks (id, artists) VALUES (1, '[{"name": "blink-182"}]'); 
INSERT INTO tracks (id, artists) VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]'); 

Część 2: Zapytanie

SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}'; 
id | artists 
----+--------- 
(0 rows) 

To zapytanie daje wynik pusty.
Próbowałem również użyć indeksów GIN jsonb_path_ops.

wskaźnik alternatywna i hasła:

DROP INDEX tracks_artists_gin_idx; 
CREATE INDEX tracks_artistnames_gin_idx ON tracks USING gin (artists jsonb_path_ops); 
SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}'; 
id | artists 
----+--------- 
(0 rows) 
+1

W mojej odpowiedzi brakowało warstwy macierzy w przykładzie, do którego się odwołujesz. To jest teraz naprawione. Odpowiedź @ potatosalad zawiera wyjaśnienie. –

+0

Dla przyszłych widzów na to pytanie, znalazłem ten link http://stackoverflow.com/a/30592076/2405689, który pokazuje, w jaki sposób zapytać 'jsonb' tablicę obiektów coś, co powyższe zapytanie ma osiągnąć. – ArchNoob

Odpowiedz

7

Ten specyficzny jsonb przykład z original answer brakowało warstwę tablicy [] wokół nie pierwotnego obiektu dla zapytania obudowy. Zostało to naprawione.

zachowanie udokumentowane dla PostgreSQL 9.4.x jsonb Containment and Existence stanów:

Ogólna zasada jest taka, że ​​zawarte obiekt musi odpowiadać obiekt zawierający co do struktury i zawartości danych

...

Jako specjalny wyjątek od ogólnej zasady, że struktury musi odpowiadać, tablica może zawierać wartość prymitywną

specjalny wyjątek pozwala nam wykonać następujące czynności:

CREATE TABLE tracks (id serial, artistnames jsonb); 
CREATE INDEX tracks_artistnames_gin_idx ON tracks USING gin (artistnames); 
INSERT INTO tracks (id, artists) VALUES (1, '["blink-182"]'); 
INSERT INTO tracks (id, artists) VALUES (2, '["The Dirty Heads", "Louis Richards"]'); 

Możemy zapytanie o zamknięcie, zgodnie z ogólną zasadą:

SELECT * FROM tracks WHERE artistnames @> '["The Dirty Heads"]'; 
id |    artistnames    
----+--------------------------------------- 
    2 | ["The Dirty Heads", "Louis Richards"] 
(1 row) 

Możemy również zapytać o powstrzymywanie za pomocą specjalny wyjątek od tej tablicy zawiera pierwotne typy:

SELECT * FROM tracks WHERE artistnames @> '"The Dirty Heads"'; 
id |    artistnames    
----+--------------------------------------- 
    2 | ["The Dirty Heads", "Louis Richards"] 
(1 row) 

Istnieją 4 typy pierwotne, które umożliwiają rozprzestrzenianie i istnienie zapytania na tablicach pracy:

  1. ciąg
  2. liczba
  3. logiczną
  4. null

Ponieważ przykład wspomniał Pan w swoim pytaniu ma do czynienia z obiektami zagnieżdżone wewnątrz tablicy, nie kwalifikują się do szczególnego wyjątku wymienionego powyżej:

CREATE TABLE tracks (id serial, artists jsonb); 
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists); 
INSERT INTO tracks (id, artists) VALUES (1, '[{"name": "blink-182"}]'); 
INSERT INTO tracks (id, artists) VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]'); 

Możemy zapytań dla powstrzymywania stosując ogólną zasadę:

SELECT * FROM tracks WHERE artists @> '[{"name": "The Dirty Heads"}]'; 
id |       artists       
----+----------------------------------------------------------- 
    2 | [{"name": "The Dirty Heads"}, {"name": "Louis Richards"}] 
(1 row) 

Obiekty nie są uważane za prymitywny typ, więc poniższe zapytanie do skażenia nie kwalifikują się do szczególnego wyjątku i dlatego nie działa:

SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}'; 
id | artists 
----+--------- 
(0 rows) 
+0

@ErwinBrandstetter Moje oryginalne sformułowanie było niewłaściwe dla opisania faktycznego problemu i niezamierzone poniżenie w kierunku twojej odpowiedzi (nie zdawałem sobie z tego sprawy, dopóki nie zobaczyłem siebie zacytowanego). Zmieniłem go, aby lepiej odzwierciedlał to, co faktycznie się wydarzyło. – potatosalad

+0

Żyjemy się uczyć. Bardzo dobra odpowiedź teraz. :) –

+0

Dzięki @ErwinBrandstetter and potatosalad – user2512324

Powiązane problemy