Есть ли способ поиска в столбце json postgres с помощью соответствующего предложения? - PullRequest
0 голосов
/ 01 марта 2020

Я пытаюсь найти запись в столбце Postgres JSON. Сохраненные данные имеют следующую структуру:

{
  "contract_shipment_date": "2015-06-25T19:00:00.000Z",
  "contract_product_grid": [
    {
      "product_name": "Axele",
      "quantity": 22.58
    },
    {
      "product_name": "Bell",
      "quantity": 52.58
    }
  ],
  "lc_status": "Awaited" 
}

Моя таблица называется Heap, а имя столбца - contract_product_grid. Кроме того, столбец contract_product_grid может содержать несколько записей продукта. Я нашел эту документацию, но не смог получить желаемый результат.

Требуется случай, у меня есть фильтр, в котором пользователи могут выбирать имя_продукта и на основе введенного имени, используя соответствующее условие, запись будет извлекается и возвращается пользователям.

Ответы [ 3 ]

0 голосов
/ 01 марта 2020

Вам необходимо удалить массив, чтобы иметь возможность использовать условие LIKE для каждого значения:

select h.*
from heap h
where exists (select * 
              from jsonb_array_elements(h.contract_product_grid -> 'contract_product_grid') as p(prod)
              where p.prod ->> 'product_name' like 'Axe%')

Если вам не нужен поиск по шаблону (поэтому = вместо LIKE) вы можете использовать оператор содержимого @>, который намного эффективнее:

select h.*
from heap h
where h.contract_product_grid -> 'contract_product_grid' @> '[{"product_name": "Axele"}]';

Также его можно использовать для поиска нескольких продуктов:

select h.*
from heap h
where h.contract_product_grid -> 'contract_product_grid' @> '[{"product_name": "Axele"}, {"product_name": "Bell"}]';

Если вы используете Postgres 12 , вы можете упростить этот бит, используя JSON path выражение:

select *
from heap
where jsonb_path_exists(contract_product_grid, '$.contract_product_grid[*].product_name ? (@ starts with "Axe")')

Или используя регулярное выражение:

select *
from heap
where jsonb_path_exists(contract_product_grid, '$.contract_product_grid[*].product_name ? (@ like_regex "axe.*" flag "i")')
0 голосов
/ 02 марта 2020

SELECT * FROM ( SELECT JSON_ARRAY_ELEMENTS(contract_product_grid::json) AS js2 FROM heaps WHERE 'contract_product_grid' = 'contract_product_grid' ) q WHERE js2->> 'product_name' IN ('Axele', 'Bell') Как, я упоминал в вопросе, что мое имя столбца 'contract_product_grid', и я должен только искать из него. Используя этот запрос, я могу получить информацию о contract_product_grid, используя предложение IN с введенным названием продукта.

0 голосов
/ 01 марта 2020

Предположим, вы ввели Axele в качестве ввода product_name и хотите вернуть соответствующее значение для клавиши quantity.

Затем используйте:

SELECT js2->'quantity' AS quantity
  FROM
  (
   SELECT JSON_ARRAY_ELEMENTS(value::json) AS js2
     FROM heap,
     JSON_EACH_TEXT(contract_product_grid) AS js
    WHERE key = 'contract_product_grid' 
  ) q
  WHERE js2->> 'product_name' = 'Axele' 

, где разверните самые внешние JSON в key & value пары через JSON_EACH_TEXT(json) и разделите все элементы с помощью вновь сформированного массива: JSON_ARRAY_ELEMENTS(value::json) функция.

Затем отфильтруйте по spesifi c product_name в основном запросе.

Демо

PS Не забудьте обернуть JSON значение столбца фигурными скобками

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