Eu tenho uma mesa para armazenar informações sobre meus coelhos. Se parece com isso:
create table rabbits (rabbit_id bigserial primary key, info json not null);
insert into rabbits (info) values
('{"name":"Henry", "food":["lettuce","carrots"]}'),
('{"name":"Herald","food":["carrots","zucchini"]}'),
('{"name":"Helen", "food":["lettuce","cheese"]}');
Como devo encontrar os coelhos que gostam de cenouras? Eu vim com isso:
select info->>'name' from rabbits where exists (
select 1 from json_array_elements(info->'food') as food
where food::text = '"carrots"'
);
Eu não gosto dessa consulta. É uma bagunça.
Como tratador de coelhos em tempo integral, não tenho tempo para alterar meu esquema de banco de dados. Eu só quero alimentar meus coelhos adequadamente. Existe uma maneira mais legível de fazer essa consulta?
json
postgresql
postgresql-9.3
Bola de neve
fonte
fonte
Respostas:
A partir do PostgreSQL 9.4, você pode usar o
?
operador :Você pode até indexar a
?
consulta na"food"
chave se alternar para o tipo jsonb :Claro, você provavelmente não tem tempo para isso como um criador de coelhos em tempo integral.
Atualização: aqui está uma demonstração das melhorias de desempenho em uma mesa de 1.000.000 de coelhos, onde cada coelho gosta de dois alimentos e 10% deles gosta de cenouras:
fonte
select * from rabbits where info->'food' != '[]';
create table t (x jsonb); insert into t (x) values ('[1,2,3]'), ('[2,3,4]'), ('[3,4,5]'); select * from t where x @> '2';
. Observe que'2'
é um número JSON; não se deixe enganar pelas aspas.Você poderia usar o operador @> para fazer algo como
fonte
'
carrapatos em torno de "cenouras" ... ele quebra se você deixá-los de fora, mesmo se estiver verificando um inteiro. (passou 3 horas tentando encontrar um número inteiro, fazendo-o funcionar magicamente envolvendo'
tiques em torno do número)'
para formar uma string, porque tudo é uma string para SQL no tipo JSONB. Por exemplo, boolean:'true'
, string:'"example"'
, inteiro:'123'
.Não mais inteligente, mas mais simples:
fonte
Uma pequena variação, mas nada de fato novo. Está realmente faltando um recurso ...
fonte