分层导航 == 分面搜索。
它们是同一个东西,但是 Magento 和 al 使用了不同的措辞,可能是为了吸引人。据我所知,Magento 支持 Solr 分面搜索或 MySQL 分面搜索。主要区别在于性能。
性能是主要的权衡。
在 MySQL 中进行分面搜索需要连接表,而 Solr 会自动索引文档分面以进行过滤。您通常可以在平均硬件上使用 Solr(多方面搜索查询<100ms)实现快速响应时间。虽然 MySQL 将花费更长的时间进行相同的搜索,但可以使用索引对其进行优化以实现相似的响应时间。
Solr 的缺点是它需要您在服务器上配置、保护和运行另一个服务。根据您的配置(Tomcat、jetty 等),它也可能会占用大量 CPU 和内存。
在 PHP/MySQL 中进行分面搜索是可能的,并不像您想象的那么难。
您需要一个特定的数据库模式,但这是可行的。这是一个简单的例子:
产品
+----+------------+
| id | name |
+----+------------+
| 1 | blue paint |
| 2 | red paint |
+----+------------+
分类
+----+----------+
| id | name |
+----+----------+
| 1 | color |
| 2 | material |
| 3 | dept |
+----+----------+
产品分类
+------------+-------------------+-------+
| 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 中实现它。