PostgreSQL обратный LIKE с шаблонами в массиве json - PullRequest
0 голосов
/ 23 сентября 2018

Этот вопрос относится к PostgreSQL Reverse LIKE

У меня есть таблица a, содержащая столбец json a.matchers.a.matchers - это массив объектов, каждый из которых имеет свойство pattern. Учитывая inputString, я хотел бы получить все строки, в которых хотя бы один из matchers[].pattern соответствовал бы inputString LIKE '%{pattern}%'

Итак, в основном (как псевдопросмотр):

SELECT * 
FROM a 
WHERE 
    'inputStringABC' LIKE ANY('%' || json_array_elements(a.matchers)->>'pattern' || '%') 

Возможно ли это?

ps: версия PostgreSQL 9.6.3

edit: более подробное описание status quo:

Таблица a:

           Column            |            Type             |                   Modifiers                   | Storage  | Stats target | Description
------------------------------+-----------------------------+-----------------------------------------------+----------+--------------+-------------
 uuid                         | uuid                        | not null default uuid_generate_v4()           | plain    |              |
 matchers                     | json                        |                                               | extended |              |

Структура JSON в сопоставлениях столбцов:

[
    {
        pattern: string;
    }
]

Пример использования:

У меня естьстрока «Некоторые деревья выглядят лучше других» и следующие строки в таблице a:

  • uuid: "123...", matchers: [{ pattern: "trees" }]
  • uuid: "987...", matchers: [{ pattern: "bees" }, { pattern: "plants" }]

Запросдолжен вернуть строку с uuid "123...", так как trees происходит в "Some trees look nicer than others"

Edit2:

последний запрос, который работал для меня благодаря s-man

SELECT DISTINCT                                                  
    uuid,
    pattern
FROM (
    SELECT 
        *, 
        jsonb_array_elements(a.matchers)->>'pattern' as pattern  
    FROM a
) s
WHERE 
    'Some trees look nicer than others' LIKE '%' || pattern || '%'   

1 Ответ

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

Таблица :

id   matchers
1    [{"abc": 1, "pattern": "ABC"}, {"pattern": "ABAB"}, {"cde": "FOO", "pattern": "AABB"}]
2    [{"pattern": "AB"}, {"cde": "BAR", "pattern": "CDE"}]
3    [{"abc": 2, "pattern": "CD"}, {"pattern": "FG"}] 

Запрос :

SELECT DISTINCT                                                  -- C
    id,
    matchers
FROM (
    SELECT 
        *, 
        jsonb_array_elements(a.matchers)->>'pattern' as pattern  -- A
    FROM a
) s
WHERE 
    pattern LIKE '%AB%'                                          -- B

A: jsonb_array_elements расширяет массив json до одной строки вэлемент массива.Оператор ->> дает значение атрибута pattern, содержащегося в каждом элементе массива, в виде текста.

B: фильтрация текстовых значений с помощью оператора LIKE

C: поскольку таблица развернутамы должны уменьшить его еще раз, поскольку нам нужны только исходные столбцы, которые мы сохранили в подзапросе в каждой строке.

Результат :

id   matchers
1    [{"abc": 1, "pattern": "ABC"}, {"pattern": "ABAB"}, {"cde": "FOO", "pattern": "AABB"}]
2    [{"pattern": "AB"}, {"cde": "BAR", "pattern": "CDE"}]

демо: db <> fiddle


Если ваш столбец имеет тип json вместо jsonb, вы должны использовать, конечно, json_array_elements.


Редактировать: После того, как вопрос стал более понятным, выяснилось, что сценарий использования шаблона является другим.Таким образом, ожидаемый результат может быть достигнут путем изменения предложения WHERE на:

'long input string including pattern' LIKE '%' || pattern || '%'

Дальнейшее чтение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...