Поиск записей с отсутствующим свойством в массиве поля JSON (MySQL)

0

У меня есть таблица, содержащая все продукты. Свойства продукта хранятся в поле JSON, называемом свойствами. Внутри объекта JSON у меня есть свойство для хранения путей изображения продукта. Структура выглядит так:

{..., "images": [{"original": "path/to/original", "icon": "path/to/icon", "small": "path/to/small"}, {"original": "path/to/original"}], ...}

Поскольку вы можете видеть, что второе изображение не имеет размеров, отличных от исходного, мое приложение должно создавать разные размеры этого изображения. Проблема в том, что я не могу фильтровать такие записи, которые не имеют свойств "маленький" или "значок" (или любого произвольного размера) в одном из массивов элементов в изображениях. Я попробовал следующее условие WHERE:

... WHERE JSON_CONTAINS_PATH(properties, 'one', '$.images') AND JSON_CONTAINS_PATH(properties, 'all', '$.images[*].icon', '$.images[*].small') = 0;

К сожалению, это не сработает. В моем понимании второй JSON_CONTAINS_PATH должен искать записи, которые пропускают значок или небольшое свойство в любом из элементов массива изображений. Ясно, что это не так.

Какую функцию JSON использовать? (если JSON_CONTAINS_PATH не подходит для этой цели) Что нужно изменить в запросе? (если это)

  • 0
    Какой результат вы ожидаете от запроса? Некоторые идеи, которые могут быть полезны, dbfiddle . Оцените возможные проблемы с производительностью.
  • 0
    Попробуй дб-скрипку .
Теги:

2 ответа

0

Мне удалось решить мою проблему, используя два разных запроса:

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

select max(json_length(properties, '$.images')) as max_nr_images from products where json_contains_path(properties, 'one', '$.images[0]') group by json_length(properties, '$.images');

И тогда я формирую условия, основанные на этом числе:

select * from products where json_contains_path(properties, 'one', '$.images[0]') and (json_contains_path(properties, 'all', '$.images[0].icon', '$.images[0].small') = 0 or if(json_contains_path(properties, 'one', '$.images[1]'), json_contains_path(properties, 'all', '$.images[1].icon', '$.images[1].small'), 1) = 0 or if(json_contains_path(properties, 'one', '$.images[2]'), json_contains_path(properties, 'all', '$.images[2].icon', '$.images[2].small'), 1) = 0 or if(json_contains_path(properties, 'one', '$.images[3]'), json_contains_path(properties, 'all', '$.images[3].icon', '$.images[3].small'), 1) = 0 or if(json_contains_path(properties, 'one', '$.images[4]'), json_contains_path(properties, 'all', '$.images[4].icon', '$.images[4].small'), 1) = 0);

(Это для четырех изображений.)

0

Я не уверен, что здесь происходит, но я не могу воссоздать вашу проблему.

MySQL [localhost+ ssl/stack] SQL> select * from q1 WHERE JSON_CONTAINS_PATH(pro
erties, 'one', '$.images') and JSON_CONTAINS_PATH(properties,'all','$.images[*]
icon','$.images[*].small');
+----+-------------------------------------------------------------------------
--------------------------------------------------------------------------+
| id | properties
                                                                          |
+----+-------------------------------------------------------------------------
--------------------------------------------------------------------------+
|  1 | {"name": "test", "images": [{"icon": "path/to/icon", "small": "path/to/s
all", "original": "path/to/original"}, {"original": "path/to/original"}]} |
+----+-------------------------------------------------------------------------
--------------------------------------------------------------------------+
1 row in set (0.0013 sec)

и json_contains_path (свойства, "все", "$. images [*]. icon") сами по себе и json_contains_path (свойства, "все", "$. images.small") сами по себе работают.

Поэтому я знаю, что найденные записи находятся. Чтобы получить "нет соответствия", мне нужна запись, которая не соответствует. Я собираюсь УБИТЬ это, чтобы новая запись не имела "малого" объекта в массиве изображений.

MySQL [localhost+ ssl/stack] SQL> insert into q1 (id,properties) values(2,'{"nam
e" : "test2", "images": [{"icon": "path/2/icon", "medium": "path2/icon"}]}');

Повторите запрос:

MySQL [localhost+ ssl/stack] SQL> select * from q1 WHERE JSON_CONTAINS_PATH(prop
erties, 'one', '$.images') and JSON_CONTAINS_PATH(properties,'all','$.images[*].
icon','$.images[*].small') = 0;
+----+--------------------------------------------------------------------------
------+
| id | properties
      |
+----+--------------------------------------------------------------------------
------+
|  2 | {"name": "test2", "images": [{"icon": "path/2/icon", "medium": "path2/ico
n"}]} |
+----+--------------------------------------------------------------------------
------+
1 row in set (0.0020 sec)

Я получаю аналогичные результаты тестирования для "значка". Поэтому я не уверен, что не работает для вас.

  • 0
    Взгляните на это: justpaste.it/7bv8q Я ожидаю, что результатом будет запись с идентификатором 5 в этом случае.
  • 0
    Да, '= 0' получает записи, которые не соответствуют требованию.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню