@ventacom

Можно ли организовать фильтр/поиск товаров посредством JSON_EXTRACT?

Есть мысль организовать поиск товаров по их характеристикам через JSON_EXTRACT. В таблицу product добавить поле params (JSON) и хранить в нем информацию по хар-кам в следующем виде:
INSERT INTO product (`params`)
 VALUES ('{
	"group1": [10, 12, 15, 16],
	"group2": [21, 27],
	"group3": [36],
	"group5": [52]
}'),
('{
	"group1": [11, 12, 17, 19],
	"group2": [22],
	"group3": [38,39],
	"group4": [48]
}'),
('{
	"group1": [12, 16],
	"group2": [20],
	"group3": [33],
	"group4": [44]
}'),
('{
	"group1": [11, 18],
	"group2": [20, 27, 29],
	"group3": [36],
	"group5": [52]
}');

где group1 - это ИД группы фильтров, а [11, 18] - это ИД значений фильтров.
При этом значения хранятся в виде массива, поскольку в рамках одной группы у товара может быть выбрано несколько значений. Например, цвет вещи (group1): красный (11) и зеленый (12); размеры (group2): S (20), M (27) и L (29) и т.п.

При этом когда фильтруются товары по данным хар-кам, то в рамках группы поиск идет по условию ИЛИ, а между группами И. То есть: (Красный ИЛИ Зеленый ИЛИ Синий) И (S ИЛИ M)

Вопрос: можно ли организовать такую выборку с помощью JSON_EXTRACT или иной функции для работы с полем JSON через sql запрос?
  • Вопрос задан
  • 200 просмотров
Пригласить эксперта
Ответы на вопрос 2
mayton2019
@mayton2019
Bigdata Engineer
Я-бы переделал табличку. Пускай мета-данные по продуктам лежат в виде битовых полей.

create table product(
  ....
  params_group1 BINARY(100),
  params_group2 BINARY(100),
  params_group3 BINARY(100)
)


И дальше булевыми (bitwise) операциями как тут пишут https://dev.mysql.com/doc/refman/8.0/en/bit-functi... делать поиски продуктов по маске свойств.
Ответ написан
batyrmastyr
@batyrmastyr
Сделать можно, но здесь вас ждёт множество граблей:
1. Крайне неэффективное хранение: объём в разы больше, чем если раскидать по таблицам.
2. Эффективность индексов по JSON полю: если в постгресе она не особо радует, но можно выбирать между простотой и скоростью работы, то в мускуле есть только убогие костыли с индексированием частей объекта через генерируемые столбцы.
3. OR = JSON_OVERLAPS, IN = JSON_CONTAINS или разворачивать вручную. И чёрт знает, сработает ли индекс потому, что это функции, а не операторы.
4. Типизация значений: в JSON можно пихнуть и '3', и 3 и 3.0. Нужно внимательно следить за типами и при сохранении, и при поиске, чтобы всё правильно находилось.

В общем, если хотите навернуть такое, то стоит крепко задуматься о переходе на постгрес, в нём хотя бы 2 и 3 проблемы не будут выглядеть неразрешимыми.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы