Postgres JSONB, запросить массив объектов - PullRequest
0 голосов
/ 09 сентября 2018

у меня есть поле jsonb, содержащее json из iiif манифестов.
я заинтересован в извлечении блока metadata, представляющего собой массив объектов json в форме

{label:"', value:""}

пример:

"metadata": [
    {
        "label": "Homepage",
        "value": "<span><a href=\"https://digital.bodleian.ox.ac.uk/inquire/p/1bac4a1e-fba6-4466-baf5-ef2d45a47ec1\">View on Digital Bodleian</a></span>"
    },
    {
        "label": "Creator",
        "value": "Exeter-'Change (London, England) [author]"
    },
    {
        "label": "Contributors",
        "value": "Incledon, Charles Benjamin, 1763-1826 [performer]"
    },
    {
        "label": "Date Statement",
        "value": "1781-11-24"
    }
]

Я бы хотел, чтобы в запросе были столбцы с именем label с относительным value для всех объектов metadata[], например:

|Creator                                    |Contributors                                     |
|-------------------------------------------|-------------------------------------------------|
|Exeter-'Change (London, England) [author]  |Incledon, Charles Benjamin, 1763-1826 [performer]|

это тривиальный запрос для составления?

1 Ответ

0 голосов
/ 09 сентября 2018

Это может быть тривиально [или нет].

Если вам известны все метки из метаданных (возможно, из-за того, что вы их извлекли ранее), вы можете использовать функцию сводной таблицы postgresql:

Сначала вам нужно включить функцию:

CREATE extension tablefunc;

тогда вы можете использовать кросс-таблицу следующим образом:

SELECT * FROM crosstab ('
    SELECT t.id as id, m->>''label'', m->>''value'' 
        FROM import.manifest t, 
             LATERAL jsonb_array_elements(t.data->''metadata'') m 
        ORDER BY 1,2
    ', '
        select distinct m->>''label'' 
            FROM import.manifest t, 
                 LATERAL jsonb_array_elements(t.data->''metadata'') m 
            order by 1
    ') AS ct (id int,Author text, Contributors text, Creator text, "Date Statement" text, Homepage text, Published text);

Вы должны поместить всю свою метку в запрос, поэтому она не так тривиальна.

Функция кросс-таблицы принимает 2 параметра:

  • Первый - это SQL, который возвращает 3 столбца:
    • Один столбец идентификатора для объединения данных
    • ключевой столбец. Текст из этого столбца будет именем столбца в результате
    • столбец значений
  • Второй - это SQL, который возвращает все столбцы, которые у вас будут.

С помощью функции вам также нужно определить результат, который вы получите. Это означает, что as ct(....) является обязательным. он должен ссылаться на столбец идентификатора и весь столбец, который вы будете иметь для возврата. для вашего случая использования это возврат:

select distinct(m->>'label') 
    FROM manifest t, LATERAL jsonb_array_elements(t.data->'metadata') m 
    order by 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...