Як зробити запит за допомогою полів у новому типі даних PostgreSQL JSON?


216

Я шукаю деякі документи та / або приклади нових функцій JSON в PostgreSQL 9.2.

Зокрема, з урахуванням серії записів JSON:

[
  {name: "Toby", occupation: "Software Engineer"},
  {name: "Zaphod", occupation: "Galactic President"}
]

Як мені написати SQL, щоб знайти запис за іменем?

У ванільному SQL:

SELECT * from json_data WHERE "name" = "Toby"

Офіційний посібник для розробників досить рідкий:

Оновити I

Я зібрав суть, в якій детально описується, що зараз можливо з PostgreSQL 9.2 . За допомогою деяких спеціальних функцій можна робити такі речі:

SELECT id, json_string(data,'name') FROM things
WHERE json_string(data,'name') LIKE 'G%';

Оновлення II

Зараз я перемістив свої функції JSON у власний проект:

PostSQL - це набір функцій для перетворення PostgreSQL та PL / v8 в абсолютно дивовижний магазин документів JSON


3
Нещодавно я знайшов цю статтю
knowbody

1
@knowbody Ця публікація насправді стосується запиту JSONB, що зовсім відрізняється від JSON. Моє погано, що я не зробив це зрозумілішим у пості.
Метью Шинкель

Відповіді:


177

Постгрес 9.2

Я цитую Ендрю Данстан у списку хакерів pgsql :

На певному етапі можливо буде функція обробки json (на відміну від json-виробника) функцій, але не в 9.2.

Це не заважає йому надати приклад реалізації в PLV8, який повинен вирішити вашу проблему.

Постгрес 9.3

Пропонує арсенал нових функцій та операторів, щоб додати "json-обробку".

Відповідь на початкове запитання в Postgres 9.3:

SELECT *
FROM   json_array_elements(
  '[{"name": "Toby", "occupation": "Software Engineer"},
    {"name": "Zaphod", "occupation": "Galactic President"} ]'
  ) AS elem
WHERE elem->>'name' = 'Toby';

Розширений приклад:

Для більших таблиць ви можете додати індекс вираження для підвищення продуктивності:

Постгрес 9.4

Додає jsonb(b для "двійкових", значення зберігаються як рідні типи Postgres) та ще більше функціональності для обох типів. Окрім згаданих вище індексів експресій, jsonbтакож підтримує GIN, btree та хеш-індекси , GIN є найбільш потужним з них.

Посібник стосується пропозицій:

Загалом, більшість програм повинніjsonb вважати за краще зберігати дані JSON , за винятком випадків, коли існують досить спеціалізовані потреби, такі як застарілі припущення щодо впорядкування ключів об'єктів.

Сміливий акцент мій.

Ефективність виграє від загальних удосконалень індексів GIN.

Постгрес 9.5

Повні jsonbфункції та оператори. Додайте більше функцій для маніпулювання jsonbна місці та для відображення.


1
Дякую, я дуже швидко стикався з проблемами типу, використовуючи підхід PLV8. Виглядає багатообіцяюче, але наразі не дуже корисно.
Тобі Хеде

@TobyHede: Гадаю, тоді нам доведеться чекати 9,3.
Ервін Брандстеттер

1
@JoeShaw: Дякую, я відповідно оновив і додав посилання на Postgres Wiki.
Erwin Brandstetter

@ErwinBrandstetter, якщо я шукаю, де elem - >> 'правильний' = 'ІСТИНА'; і JSON виглядає так: "правильно": "ІСТИНА", що це правильний спосіб запитувати логічні умови?
Ширай

@Shiraj: Будь-ласка, запитайте нові запитання . Коментарі - це не місце.
Ервін Брандстетер

87

З Postgres 9.3+, просто використовуйте ->оператор. Наприклад,

SELECT data->'images'->'thumbnail'->'url' AS thumb FROM instagram;

дивіться на http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/ кілька приємних прикладів та навчальний посібник.


2
У наведеному вище прикладі ви повинні мати поле з ім'ям dataз документом JSON: {images:{thumbnail:{url:'thumbnail.jpg'}}}. Повідомте нас, як виглядають ваші дані та які запити не вдається.
Meekohi


6
Як можна запитати, чи є масив? Я бачу оператора # >>, але немає підказки, як ним користуватися!
Мохамед Ель Махаллаї

Чи можу я використати підстановку для цього вибору запиту? ТобтоSELECT data->'%'->'thumbnail'->'url' AS thumb FROM instagram;
Бхарат

@ Meekohi відповідь працює добре: конкретно, мені не потрібно було, ::jsonяк описано в інших публікаціях. Також зауважте, що ->оператор видасть помилку, якщо ви спробуєте отримати доступ до нерухомості, яка не існує (тобто, якщо ви похизувались JSON):ERROR: column "jsonPropertyYouWant" does not exist
Red Pea

19

З postgres 9.3 використання -> для доступу до об'єктів. 4 приклад

насіннє.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

рейки c

SELECT data->'params'->0 as data FROM smart_elements;

повертає

                                 data
----------------------------------------------------------------------
 {"type":1,"code":1,"value":2012,"description":"year of producction"}
(1 row)

Можна продовжувати гніздування

SELECT data->'params'->0->'type' as data FROM smart_elements;

повернення

 data
------
 1
(1 row)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.