¿Cómo puedo realizar consultas usando campos dentro del nuevo tipo de datos JSON de PostgreSQL?
Estoy buscando algunos documentos y/o ejemplos para las nuevas funciones JSON en PostgreSQL 9.2.
Específicamente, dada una serie de registros JSON:
[
{name: "Toby", occupation: "Software Engineer"},
{name: "Zaphod", occupation: "Galactic President"}
]
¿Cómo escribiría el SQL para encontrar un registro por nombre?
En vanilla SQL:
SELECT * from json_data WHERE "name" = "Toby"
El manual oficial dev es bastante sparse:
- http://www.postgresql.org/docs/devel/static/datatype-json.html
- http://www.postgresql.org/docs/devel/static/functions-json.html
Actualización I
He reunido un gist detallando lo que es posible actualmente con PostgreSQL 9.2. Usando algunas funciones personalizadas, es posible hacer cosas como:
SELECT id, json_string(data,'name') FROM things
WHERE json_string(data,'name') LIKE 'G%';
Actualización II
Ahora he movido mis funciones JSON a sus propias proyecto:
PostSQL - un conjunto de funciones para transformar PostgreSQL y PL/v8 en un almacén de documentos JSON totalmente impresionante
3 answers
Postgres 9.2
Cito Andrew Dunstan en la lista de hackers de pgsql :
En algún momento posiblemente habrá algún procesamiento json (a diferencia de json), pero no en la versión 9.2.
No le impide proporcionar una implementación de ejemplo en PLV8 que debería resolver su problema.
Postgres 9.3
Ofrece un arsenal de nuevas funciones y operadores para agregar "json-procesamiento".
- El manual sobre la nueva funcionalidad JSON.
- El Wiki de Postgres sobre nuevas características en pg 9.3.
- @Will publicó un enlace a un blog demostrando los nuevos operadores en a comentarios debajo de.
La respuesta a la pregunta original en Postgres 9.3:
SELECT *
FROM json_array_elements(
'[{"name": "Toby", "occupation": "Software Engineer"},
{"name": "Zaphod", "occupation": "Galactic President"} ]'
) AS elem
WHERE elem->>'name' = 'Toby';
Ejemplo avanzado:
Para tablas más grandes es posible que desee agregar un índice de expresión para aumentar el rendimiento:
Postgres 9.4
Añade jsonb
(b para "binario", los valores se almacenan como tipos Postgres nativos) y aún más funcionalidad para ambos tipos. Además de los índices de expresión mencionados anteriormente, jsonb
también admite índices de GINEBRA, btree y hash , siendo el más potente de estos.
- El manual sobre
json
yjsonb
tipos de datos y funciones. - El Wiki de Postgres sobre JSONB en pg 9.4
El manual va tan lejos como sugerir:
En general, la mayoría de las aplicaciones deberían preferir almacenar datos JSON como
jsonb
, a menos que haya necesidades bastante especializadas, como el legado suposiciones sobre el orden de las claves de objeto.
Énfasis en negrita mina.
El rendimiento se beneficia de las mejoras generales de los índices de GINEBRA.
Postgres 9.5
Completa jsonb
funciones y operadores. Agregue más funciones para manipular jsonb
en su lugar y para mostrar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:24
Con Postgres 9.3+, simplemente use el operador ->
. Por ejemplo,
SELECT data->'images'->'thumbnail'->'url' AS thumb FROM instagram;
Véase http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json / para algunos buenos ejemplos y un tutorial.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-01 22:57:30
Con postgres 9.3 use -> para el acceso a objetos. 4 ejemplo
Semilla.rb
se = SmartElement.new
se.data =
{
params:
[
{
type: 1,
code: 1,
value: 2012,
description: 'year of producction'
},
{
type: 1,
code: 2,
value: 30,
description: 'length'
}
]
}
se.save
Carriles c
SELECT data->'params'->0 as data FROM smart_elements;
Devuelve
data
----------------------------------------------------------------------
{"type":1,"code":1,"value":2012,"description":"year of producction"}
(1 row)
Puede continuar anidando
SELECT data->'params'->0->'type' as data FROM smart_elements;
Return
data
------
1
(1 row)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-27 12:27:51