Mam tabelę, persons
która zawiera dwie kolumny id
oraz data
kolumnę opartą na JSONB (ta tabela została właśnie stworzona w celach demonstracyjnych do zabawy z obsługą JSON w PostgreSQL).
Teraz przypuszcza, że zawiera dwa rekordy:
1, { name: 'John', age: 30 }
2, { name: 'Jane', age: 20 }
Teraz przypuszczam, że chcę uzyskać imię każdej osoby w wieku powyżej 25 lat. Próbowałem:
select data->'name' as name from persons where data->'age' > 25
Niestety powoduje to błąd. Mogę rozwiązać to za pomocą ->>
zamiast ->
, ale wtedy porównania nie działają już zgodnie z oczekiwaniami, ponieważ nie porównuje się liczb, ale ich reprezentacje jako ciągi znaków:
select data->'name' as name from persons where data->>'age' > '25'
Potem zorientowałem się, że mogę rozwiązać problem, używając ->
i obsady int
:
select data->'name' as name from persons where cast(data->'age' as int) > 25
To działa, ale nie jest miło, że muszę znać rzeczywisty typ (typ age
dokumentu JSON jest number
zresztą, więc dlaczego PostgreSQL nie może tego sam zrozumieć?).
Potem zorientowałem się, że jeśli ręcznie przekonwertuję na text
użycie ::
składni, wszystko też działa zgodnie z oczekiwaniami - chociaż teraz ponownie porównujemy łańcuchy.
select data->'name' as name from persons where data->'age'::text > '25'
Jeśli następnie wypróbuję to z nazwą zamiast wieku, to nie działa:
select data->'name' as name from persons where data->'name'::text > 'Jenny'
Powoduje to błąd:
niepoprawna składnia wejściowa dla typu json
Najwyraźniej nic tu nie rozumiem. Niestety, ciężko jest znaleźć rzeczywiste przykłady użycia JSON z PostgreSQL.
Jakieś wskazówki?
'Jenny'
się '"Jenny"'
.
data->'name'::text
rzutujesz'name'
ciąg na tekst, a nie wynik. Nie pojawia się błąd przy porównywaniu,'25'
ponieważ25
jest to prawidłowy literał JSON; aleJenny
nie jest (chociaż"Jenny"
byłoby).