Ответ 1
Слоистая навигация == Граничный поиск.
Это одно и то же, но Magento и al используют разные формулировки, вероятно, быть броскими. Насколько я знаю, Magento поддерживает как Solr-фасетный поиск, так и MySQL. Основное отличие - производительность.
Производительность является основным компромиссом.
Для выполнения фасетного поиска в MySQL требуется объединение таблиц, в то время как Solr автоматически индексирует графы документа для фильтрации. Обычно вы можете получить быстрое время отклика с помощью Solr (< 100ms для многоаспектного поискового запроса) на среднем оборудовании. Хотя MySQL займет больше времени для одного и того же поиска, его можно оптимизировать с помощью индексов для достижения аналогичного времени отклика.
Недостатком Solr является то, что для него требуется настроить безопасный и запустить еще одну услугу на вашем сервере. Он также может быть довольно интенсивным с процессором и памятью в зависимости от вашей конфигурации (Tomcat, причал и т.д.).
Граничный поиск в PHP/MySQL возможен, и не так сложно, как вы думаете.
Вам нужна конкретная схема базы данных, но это возможно. Вот простой пример:
продукт
+----+------------+
| id | name |
+----+------------+
| 1 | blue paint |
| 2 | red paint |
+----+------------+
классификация
+----+----------+
| id | name |
+----+----------+
| 1 | color |
| 2 | material |
| 3 | dept |
+----+----------+
product_classification
+------------+-------------------+-------+
| product_id | classification_id | value |
+------------+-------------------+-------+
| 1 | 1 | blue |
| 1 | 2 | latex |
| 1 | 3 | paint |
| 1 | 3 | home |
| 2 | 1 | red |
| 2 | 2 | latex |
| 2 | 3 | paint |
| 2 | 3 | home |
+------------+-------------------+-------+
Итак, скажите, что кто-то ищет paint
, вы бы сделали что-то вроде:
SELECT p.* FROM product p WHERE name LIKE '%paint%';
Это приведет к возврату обеих записей из таблицы product
.
Как только ваш поиск выполнен, вы можете получить связанные грани (фильтры) вашего результата с помощью запроса, подобного этому:
SELECT c.id, c.name, pc.value FROM product p
LEFT JOIN product_classification pc ON pc.product_id = p.id
LEFT JOIN classification c ON c.id = pc.classification_id
WHERE p.name LIKE '%paint%'
GROUP BY c.id, pc.value
ORDER BY c.id;
Это даст вам что-то вроде:
+------+----------+-------+
| id | name | value |
+------+----------+-------+
| 1 | color | blue |
| 1 | color | red |
| 2 | material | latex |
| 3 | dept | home |
| 3 | dept | paint |
+------+----------+-------+
Итак, в вашем результирующем наборе вы знаете, что есть продукты с цветом blue
и red
, что единственным материалом, из которого он сделан, является latex
и что его можно найти в отделах home
и paint
.
Как только пользователь выбирает фасет, просто измените исходный поисковый запрос:
SELECT p.* FROM product p
LEFT JOIN product_classification pc ON pc.product_id = p.id
WHERE
p.name LIKE '%paint%' AND (
(pc.classification_id = 1 AND pc.value = 'blue') OR
(pc.classification_id = 3 AND pc.value = 'home')
)
GROUP BY p.id
HAVING COUNT(p.id) = 2;
Итак, здесь пользователь ищет ключевое слово paint
и включает в себя две грани: фасет blue
для цвета и home
для отдела. Это даст вам:
+----+------------+
| id | name |
+----+------------+
| 1 | blue paint |
+----+------------+
Итак, в заключение. Хотя он доступен из коробки в Solr, его можно легко реализовать в SQL.