Tengo una mesa para almacenar información sobre mis conejos. Se parece a esto:
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"]}');
¿Cómo puedo encontrar los conejos a los que les gustan las zanahorias? Se me ocurrió esto:
select info->>'name' from rabbits where exists (
select 1 from json_array_elements(info->'food') as food
where food::text = '"carrots"'
);
No me gusta esa consulta. Es un desastre.
Como cuidador de conejos a tiempo completo, no tengo tiempo para cambiar el esquema de mi base de datos. Solo quiero alimentar adecuadamente a mis conejos. ¿Existe una forma más legible de hacer esa consulta?
json
postgresql
postgresql-9.3
Bola de nieve
fuente
fuente
Respuestas:
A partir de PostgreSQL 9.4, puede utilizar el
?
operador :Incluso puede indexar la
?
consulta en la"food"
clave si cambia al tipo jsonb en su lugar:Por supuesto, probablemente no tengas tiempo para eso como cuidador de conejos a tiempo completo.
Actualización: Aquí hay una demostración de las mejoras de rendimiento en una mesa de 1,000,000 de conejos donde a cada conejo le gustan dos alimentos y al 10% de ellos le gustan las zanahorias:
fuente
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';
. Tenga en cuenta que'2'
es un número JSON; no se deje engañar por las citas.Podrías usar el operador @> para hacer esto algo como
fuente
'
garrapatas que rodean las "zanahorias" ... se rompe si las dejas fuera, incluso si estás buscando un número entero. (Pasé 3 horas tratando de encontrar un número entero, haciéndolo funcionar mágicamente envolviendo'
garrapatas alrededor del número)'
ticks para formar una cadena, porque todo es una cadena para SQL en tipo JSONB. Por ejemplo, boolean:'true'
, cadena:'"example"'
, número entero:'123'
.No más inteligente sino más simple:
fuente
Una pequeña variación pero nada nuevo de hecho. Realmente le falta una característica ...
fuente