代码之家  ›  专栏  ›  技术社区  ›  gokujou

寻找标记系统的起点[关闭]

  •  0
  • gokujou  · 技术社区  · 16 年前

    基本上,我想建立一个标记系统,如堆栈溢出对条目,并试图计划如何基于相关性的搜索工作。我想有一个选项,为一个相关的条目部分拉相似的标记条目。现在我使用两个表作为标记,一个表用于每个唯一的标记,一个连接表。我在想,这是否能产生一个共享相似标签的条目列表。

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

    3 回复  |  直到 16 年前
        1
  •  1
  •   zerkms    16 年前

    将另一个字段添加到实体表:标记。使用逗号分隔的标记字符串,以防止选择实体列表时出现两个以上的连接。

        2
  •  1
  •   Stephen Curran    16 年前

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

    EntryId RelatedEntryId
    

    然后可以让cron作业定期重新计算关系并更新表。这将比试图快速计算这些关系要便宜得多。

        3
  •  1
  •   tadamson    16 年前

    您需要跟踪一个标记链接到另一个标记的频率。比如说,“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)
    );
    

    然后,对于绑定到文章的每个唯一标记,循环遍历所有其他标记并插入/更新,将关系计数递增1。这意味着(“php”、“mysql”)和(“mysql”、“php”)是要维护的两个完全不同的关系,但如果不深入研究我可能已经忘记的搜索概念,它仍然可以工作。如果某个东西有10+个标签,更新会非常慢(可能会像stephenc建议的那样传递给cron),但这样搜索会更容易。很好,很直截了当:

    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 同样,使用类似的想法。