【问题标题】:Faceted Search (solr) vs Good old filtering via PHP?分面搜索(solr)与通过 PHP 进行的旧过滤?
【发布时间】:2011-08-31 11:40:12
【问题描述】:

我计划在我的电子商务商店中设置过滤系统(优化您的搜索)。你可以在这里看到一个例子:http://www.bettymills.com/shop/product/find/Air+and+HVAC+Filters

PrestaShop、OpenCart 和 Magento 等平台都有所谓的分层导航。

我的问题是,与使用 Solr 或 Lucene 等平台进行多面导航相比,Magento 或 PrestaShop 等平台中的分层导航有什么区别。

仅通过 php 和 mysql 可以实现类似的结果吗?

非常感谢详细的解释。

【问题讨论】:

    标签: php magento solr faceted-search layered-navigation


    【解决方案1】:

    分层导航 == 分面搜索。

    它们是相同的东西,但 Magento 和 al 使用不同的措辞,可能是为了吸引人。据我所知,Magento 支持 Solr 分面搜索或 MySQL 分面搜索。主要区别在于性能。

    性能是主要的权衡。

    要在 MySQL 中进行分面搜索,您需要连接表,而 Solr 会自动索引文档分面以进行过滤。您通常可以在平均硬件上使用 Solr(多方面搜索查询

    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 |
    +------+----------+-------+
    

    因此,在您的结果集中,您知道有颜色为bluered 的产品,它的唯一材料是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 中实现它却相当容易。

    【讨论】:

    • 在具有多个方面的嵌套和语句中构造它的最佳方法是什么?每个方面都应该跟一个 OR 吗?
    • @RPM:是的。因为您希望 MySQL 匹配一个方面或另一个方面,然后使用 HAVING 子句检查是否所有方面都匹配(您不能告诉 MySQL 使用 AND 匹配两个方面,因为它是不可能的,因为它的关系性质,例如:value 不能同时是 bluered)。因此,如果您有 4 个方面,则需要三个带有 OR 子句的条件,以及 4HAVING COUNT()
    • @RPM:是的,所有方面都在嵌套的AND 中。模式如下。当使用OR 子句时,MySQL 将为匹配的每个方面返回一个或多个行,具有相同的p.id(项目)。因此,如果您的项目 (p.id = 1) 与 bluepaint 匹配,您将有两行:p.id=1, value=bluep.id=1, value=paintHAVING 子句确保您确实有两行,一个用于选择的每个方面。删除GROUP BY 子句,你就会明白我的意思了。
    • @RPM:不完全确定你的意思。您可能想打开一个问题并链接到这个问题,它会更容易为您解释,也更容易为我和其他用户回答。在 cmets 中解释复杂的 SQL 查询有点困难。 ;-)
    • 最后查询也可以是SELECT p.* FROM product p LEFT JOIN product_classification pc1 ON pc1.product_id = p.id LEFT JOIN product_classification pc2 ON pc2.product_id = p.id WHERE p.name LIKE '%paint%' AND pc1.classification_id = 1 AND pc1.value = 'blue' pc2.classification_id = 3 AND pc2.value = 'home'
    【解决方案2】:

    Magento 企业版实现了具有分面搜索的 Solr。你仍然需要配置 Solr 来索引正确的数据;即 Solr 在具有特定端口的主机上的 Java 上运行。 Magento 通过给定的 url 连接到它。当 Magento 设置分面搜索时,它会向 Solr 发出请求,并将接收到的 xml 处理成前端的表单。 不同之处在于速度之一。请求 Solr 非常快。如果您的商店中有大约 100,000 多种产品并希望快速响应搜索请求,则可以使用 Solr。但是,如果您有一个用于 Magento 数据库的单独服务器并具有大量内存,您也可以只使用 Magento 内置的基于 Mysql 的分面搜索。如果您没有钱购买 Magento EE,可以使用 this solr implementation。但是我没有这方面的经验。

    【讨论】:

      【解决方案3】:

      在 solr 框外,您可以使用计算的 facet、范围、选择一个 facet 或排除一个 facet,声明一个 facet 是单值还是多值,且 CPU/RAM 成本非常低

      另一方面,设置参数和保护 solr 安装需要一些时间,抓取数据也需要一些时间。

      【讨论】:

        【解决方案4】:

        您可以只使用 PHP 和 MySQL 创建分面搜索,Drupal Faceted Search 就是一个很好的例子。但是,如果您已经使用 Solr,则可以免费获得分面搜索。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-23
          • 2014-10-22
          • 1970-01-01
          相关资源
          最近更新 更多