Поиск массива jsonb в PostgreSQL

Я пытаюсь выполнить поиск объекта JSONB в PostgreSQL 9.4. Мой вопрос похож на этот поток.

Однако моя структура данных немного отличается, что вызывает у меня проблемы. Моя структура данных похожа:

[
    {"id":1, "msg":"testing"}
    {"id":2, "msg":"tested"}
    {"id":3, "msg":"nothing"}
]

и я хочу искать соответствующие объекты в этом массиве через msg (RegEx, LIKE, = и т.д.). Чтобы быть более конкретным, я хочу, чтобы все строки в таблице, где поле JSONB имеет объект с "msg", который соответствует моему запросу.

Ниже показана структура, аналогичная той, что у меня есть:

SELECT * FROM 
    (SELECT 
        '[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data) 
    as jsonbexample;

Это показывает попытку реализовать ответ на указанную выше ссылку, но не работает (возвращает 0 строк):

SELECT * FROM 
    (SELECT 
        '[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data) 
    as jsonbexample 
WHERE 
    (data #>> '{msg}') LIKE '%est%';

Может ли кто-нибудь объяснить, как искать массив JSONB? В приведенном выше примере я хотел бы найти любую строку в таблице, чье поле данных "данные" JSONB содержит объект, где "msg" что-то соответствует (например, LIKE '% est%').


Update

Этот код создает новый тип (необходим для последующего):

CREATE TYPE AlertLine AS (id INTEGER, msg TEXT);

Затем вы можете использовать это, чтобы разделить столбец с помощью JSONB_POPULATE_RECORDSET:

SELECT * FROM 
    JSONB_POPULATE_RECORDSET(
        null::AlertLine, 
        (SELECT '[{"id":1,"msg":"testing"},
                  {"id":2,"msg":"tested"},
                  {"id":3,"msg":"nothing"}]'::jsonb 
         as data
        )
    ) as jsonbex;

Выходы:

 id |   msg   
----+---------
  1 | testing
  2 | tested
  3 | nothing

И добавив ограничения:

SELECT * FROM 
    JSONB_POPULATE_RECORDSET(
        null::AlertLine, 
        (SELECT '[{"id":1,"msg":"testing"},
                  {"id":2,"msg":"tested"},
                  {"id":3,"msg":"nothing"}]'::jsonb 
         as data)
        ) as jsonbex 
WHERE 
    msg LIKE '%est%';

Выходы:

id |   msg   
---+---------
 1 | testing
 2 | tested

Итак, часть оставшегося вопроса заключается в том, как поместить это как предложение в другой запрос.

Итак, если выведенный выше код = x, как бы я спросил:

SELECT * FROM mytable WHERE x > (0 rows);

Ответ 1

Вы можете использовать exists:

SELECT * FROM 
    (SELECT 
        '[{"id":1,"msg":"testing"},{"id":2,"msg":"tested"},{"id":3,"msg":"nothing"}]'::jsonb as data) 
    as jsonbexample 
WHERE 
    EXISTS (SELECT 1 FROM jsonb_array_elements(data) as j(data) WHERE (data#>> '{msg}') LIKE '%est%');

Чтобы запросить таблицу, как указано в комментарии ниже:

SELECT * FROM atable 
WHERE EXISTS (SELECT 1 FROM jsonb_array_elements(columnx) as j(data) WHERE (data#>> '{msg}') LIKE '%est%');