寻找标记系统的起点

时间:2010-02-15 23:04:36

标签: php mysql tags

基本上我想设置像堆栈溢出这样的标记系统用于条目并试图规划基于相关性的搜索如何工作。我想有一个选项来为相关条目部分提取类似的标记条目。现在我使用两个表作为标签,每个唯一标签的表和一个连接表。我正在考虑是否能够生成共享相似标签的条目列表。

如果有人有任何想法,或链接到我可以阅读的文章,以使我的大脑朝着正确的方向前进,这将是惊人的。谢谢!

3 个答案:

答案 0 :(得分:1)

向实体表添加一个字段:标签。使用逗号分隔的标记字符串,以防止选择实体列表的另外2个连接。

答案 1 :(得分:1)

也许你可以有一个单独的表来存储相关的条目。

EntryId RelatedEntryId

然后您可以让CRON作业定期重新计算关系并更新表。它比试图动态计算这些关系要便宜。

答案 2 :(得分:1)

您需要跟踪一个标记与另一个标记链接的频率。比如,说“php”和“mysql”分享了50篇文章(或者被标记的主要内容是什么),而“php”和“sql-server”可能有3个,而“php”和“apache”有25个。所以给定“php”,你想要按顺序返回“mysql”和“apache”(可能让“sql-server”掉线)。

这绝对不是理想的,只是大声思考(现在我已经看到了斯蒂芬克的答案):

CREATE TABLE tag_relations (
tag_id int unsigned not null,
related_tag_id int unsigned not null,
relation_count smallint unsigned not null,
PRIMARY KEY (tag_id, related_tag_id),
KEY relation_count (relation_count)
);

然后对于绑定到文章的每个唯一标记,循环遍历所有其他标记和INSERT / UPDATE,将relation_count递增1.这意味着(“php”,“mysql”)和(“mysql”,“php”)两个完全不同的关系要维持,但没有挖掘我可能忘记的搜索概念,它仍然会起作用。如果某些东西有10个以上的标签,那么更新速度会非常慢(也许会将其传递给像stephenc建议的那样),但搜索方式会更容易。很好,很直白:

SELECT related_tag_id, COUNT(relation_count) AS total_relations
FROM tag_relations
WHERE tag_id IN ([list,of,tag,IDs,to,compare])
// AND tag_id NOT IN ([list,of,tag,IDs,to,compare]) -- probably
GROUP BY related_tag_id
ORDER BY total_relations DESC

比检查tag_id和& related_tag_id并且至少通过一堆子查询来总结它们。在您的代码表上加入以获取实际的代码名称&你已经确定了。

因此,如果您正在查找“php”和“mysql”,并且“apache”通常与两者相关,那么它将接近顶部,因为它正在计算&加权每个共同关系。但是,它不会严格限制为公共链接,因此添加HAVING total_relations >= x(x是任意截止值)和/或只是常规LIMIT x以保持相关性。

(注意:在考虑这个问题之前,先研究一下这个问题,我认为这里有一些已知的算法是100倍更聪明,我只是不记得了。)

PHPro.org也有一个good writeup,使用了类似的想法。