PHP,MySQL,高效的标签驱动搜索算法
我现在正在建一家网店。该商店允许用户按PHP,MySQL,高效的标签驱动搜索算法,php,mysql,performance,search,tags,Php,Mysql,Performance,Search,Tags,我现在正在建一家网店。该商店允许用户按类别过滤产品,以及一些可选的附加过滤器,如品牌,颜色等 目前,各种属性存储在不同的位置,但我想切换到基于标记的系统。理想情况下,我的数据库应该存储带有以下数据的标记: 产品标识 标记url\u别名(唯一) 标签类型(唯一)(类别、产品品牌、产品颜色等) 标记值(非唯一) 第一目标 我想搜索与1-5个特定标签之间的任何位置相关的产品id。这些标签是从一个SEO友好的url中提取的。因此,我将为每个标记检索一个唯一的字符串(标签url别名),但我不知道标签类
类别
过滤产品,以及一些可选的附加过滤器,如品牌
,颜色
等
目前,各种属性存储在不同的位置,但我想切换到基于标记的系统。理想情况下,我的数据库应该存储带有以下数据的标记:
产品标识
(唯一)标记url\u别名
(唯一)(类别、产品品牌、产品颜色等)标签类型
(非唯一)标记值
产品id
。这些标签是从一个SEO友好的url中提取的。因此,我将为每个标记检索一个唯一的字符串(标签url别名),但我不知道标签类型。
搜索将是一个交叉点,因此我的搜索应返回与所提供的标签
的所有匹配的产品id
第二个目标
除了显示与当前过滤器匹配的产品外,我还想显示用户可能提供的其他类别和过滤器的产品数量
例如,我当前搜索的是与标签匹配的产品:
Shoe + Black + Adidas
现在,该店的一位游客可能正在观看由此产生的产品,并想知道其他品牌有哪些黑鞋可供选择。因此,他们可能会去“品牌”过滤器,选择任何其他上市品牌。假设他们有两个不同的选项(实际上,这可能会有更多),导致以下搜索:
Shoe + Black + Nike > 103 results
Shoe + Black + K-swiss > 0 results
在这种情况下,如果他们在过滤器中看到品牌“K-swiss”作为可用选项列出,他们的搜索将返回0个结果
这显然是相当令人失望的用户。。。我更希望知道,将“品牌”从“阿迪达斯”切换到“k-swiss”将不会产生任何结果,只需从过滤器中删除整个选项即可
类别、颜色等也是如此
实际上,这意味着一个页面视图不仅会返回我的主要目标中描述的过滤产品列表,还可能返回数百个类似但不同的列表。每个筛选器值一个,可以替换另一个筛选器值,或添加到现有筛选器值
容量
我怀疑我的数据库最终将包含:
250到1000个唯一标记之间
它将包括:
10.000至10.000种独特产品
当前想法
我在谷歌搜索了一下,发现了以下文章:
从那篇文章来看,运行数百个查询以实现第二个目标将是一条非常缓慢的路线。“toxy”示例可能适合我的需要,对于我的第一个目标来说可能是可以接受的,但是对于第二个目标来说,它的速度太慢了,令人无法接受
我在想,我可能会运行单个查询,将1tag
与其关联的product\u id
匹配,缓存这些查询,然后计算结果的交点。但是,我在MySQL中计算这些交点吗?还是用PHP?如果我使用MySQL,是否有一种特殊的方法可以缓存这些单独的查询,或者提供我所需要的所有正确的索引
我可以想象,甚至可以缓存这两个
标签
/产品id
集合之间的交点。交叉点的数量将受到以下事实的限制:tag_type
只能有一个特定值,但我不确定如何有效地管理这种类型的缓存。同样,我不知道我应该在MySQL还是PHP中这样做。如果我在MySQL中这样做,存储和组合这种类型的缓存结果的最佳方式是什么?我还没有测试过,但是应该可以有一个查询来满足第二个目标,而不是触发几百个查询。。。
下面的查询说明了这通常应该如何工作。
其思想是一次将三个不同的请求组合起来,并按专用值分组,只收集有结果的请求
SELECT t1.product_id, count(*) FROM tagtable t1, tagtable t2, tagtable t3 WHERE
t1.product_id = t2.product_id AND
t2.product_id = t3.product_id AND
t1.tag_type='yourcategoryforShoe' AND t1.tag_value='Shoe' AND
t2.tag_type='product_color' AND t2.tag_value='Black' AND
t3.tag_type='brand'
GROUP BY t3.tag_value
HAVING count(*) > 0
使用可以为你创造奇迹。它的速度非常快,甚至可以处理wordforms,这对SEO请求非常有用
对于sphinx,制作一个文档“产品”,按标签索引,选择合适的查询等级(例如,匹配所有单词),并使用不同的标签组合运行批处理请求,以获得最佳结果。
别忘了使用memcahed或其他任何缓存。好吧,这就是我所说的问题!祝贺你,先生,谢谢你!我打赌这些答案会给我带来很多新知识!听起来很聪明!我要对它进行一些性能测试……好吧,听起来很有趣。我想知道他们的SQL支持是否包括类似于@eX0du5建议的查询。。。然后,我可能可以使用一个专门的高性能搜索引擎和一些非常智能的查询,而不是一大堆简单的查询。Sphinx确实支持类似mysql的查询语法模式,称为SphinxQL,但我更喜欢使用本机调用