首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL,高效的标签驱动搜索算法

MySQL,高效的标签驱动搜索算法
EN

Stack Overflow用户
提问于 2012-10-15 14:30:26
回答 2查看 8.3K关注 0票数 11

我正在建一家网店。该商店允许用户通过category过滤产品,以及一些可选的、附加的过滤器,如brandcolor等。

目前,不同的属性存储在不同的地方,但我想切换到一个基于标签的系统。理想情况下,我的数据库应该使用以下数据存储标记:

  • product_id
  • tag_url_alias (唯一)
  • tag_type (唯一)(类别、product_brand、product_color等)
  • tag_value (非唯一)

第一个目标

我想搜索与anywhere product_id相关的1到5特定标签。这些标签是从一个SEO友好的url中提取出来的。所以我将为每个标签检索唯一的字符串( tag_url_alias),但我不知道tag_type。搜索将是一个tag_type,所以我的搜索应该返回与提供的tagsall相匹配的product_id's。

第二个目标

除了显示与当前过滤器匹配的产品外,我还想显示用户可能提供的其他类别和过滤器的产品计数。

例如,我目前搜索的是与标签匹配的产品:

代码语言:javascript
复制
Shoe + Black + Adidas

现在,这家商店的一位游客可能会看到由此产生的产品,并想知道其他品牌必须提供哪种黑色鞋子。因此,他们可能会去“品牌”过滤器,并选择任何其他上市品牌。假设他们有两个不同的选项(在实践中,这可能会有更多的选项),结果如下:

代码语言:javascript
复制
Shoe + Black + Nike > 103 results
Shoe + Black + K-swiss > 0 results

在这种情况下,如果他们看到品牌“K-瑞士人”作为一个可用的选择在他们的过滤器,他们的搜索将返回0的结果。

显然这对用户来说是相当令人失望的。我更愿意知道,将“品牌”从“阿迪达斯”切换到“k-瑞士人”将产生0,并将整个选项从过滤器中删除。

同样的事情也适用于类别、颜色等。

实际上,这意味着单个页面视图不仅会返回我的主要目标中描述的过滤产品列表,而且可能会返回数百个类似但不同的列表。可替换另一个筛选值或添加到现有筛选值的每个筛选值的一个。

容量

我怀疑我的数据库最终会包含:

在250个到1.000个唯一标签之间

它将包括:

在10.000到100.000之间的独特产品

当前思想

我做了一些谷歌搜索,发现了以下文章:http://www.pui.ch/phred/archives/2005/06/tagsystems-performance-tests.html

从这篇文章来看,运行数百个查询以实现第二个目标,将是一条缓慢得令人痛苦的道路。“毒瘾”的例子也许能满足我的需要,对我的第一个目标来说也是可以接受的,但对于第二个目标来说,它会慢得令人无法接受。

我在想,我可能会运行单独的查询,将1 tag与其关联的product_id匹配,缓存这些查询,然后计算结果的交叉点。但是,我是在MySQL中计算这些交叉点吗?还是用PHP计算?如果我使用MySQL,是否应该缓存这些单独的查询,或者提供我所需要的正确的索引?

我可以想象,甚至有可能缓存这两个tag/product_id集之间的交叉点。tag_type只能有一个特定的值,但我不知道如何有效地管理这种类型的缓存,这将限制交叉口的数量。再说一遍,我不知道我应该用MySQL还是PHP来完成这个任务。如果我在MySQL中这样做,那么存储和组合这种缓存结果的最佳方法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-15 14:50:55

使用狮身人面像搜索引擎可以为您带来魔力。它非常快,甚至可以处理文字形式,什么是有用的SEO请求。

对于狮身人面像,制作一个文档--“产品”,按标签索引,选择合适的ranker进行查询(例如,MATCH_ALL_WORDS),并以不同的标签组合运行批处理请求,以获得最佳的结果。别忘了使用像纪念品或其他任何东西一样的看台。

票数 3
EN

Stack Overflow用户

发布于 2012-10-15 14:40:26

我还没有测试这个,但是应该可以有一个查询来满足您的第二个目标,而不是触发几百个查询.下面的查询说明了一般情况下应该如何工作。其思想是一次将三种不同的请求组合在一起,并根据所指定的值进行分组,只收集那些有结果的请求。

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12897817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档