按匹配标记的数量排序匹配标记的项目

时间:2010-09-24 02:52:25

标签: mysql search tags sphinx

我正在尝试弄清楚如何通过匹配的标签数量来订购带有匹配标签的商品。

假设您有三个MySQL表:

  • tags(tag_id, title)
  • articles(article_id, some_text)
  • articles_tags(tag_id, article_id)

现在让我们说你有四篇文章:

article_id = 1标记为“幽默”,“有趣”和“搞笑”。

article_id = 2标记为“有趣”,“愚蠢”和“高飞”。

article_id = 3标记为“有趣”,“愚蠢”和“高飞”。

article_id = 4标记为“完全严重”。

您需要通过至少一个匹配标记找到与article_id = 2相关的所有文章,并按最佳匹配顺序返回结果。换句话说,article_id = 3应该是第一位的,article_id = 1秒,而article_id = 4根本不会显示。

这是在SQL查询中单独使用的东西,还是更适合像Sphinx这样的东西?如果是前者,应该进行什么样的查询,以及应该为最高效的结果创建什么类型的索引?如果是后者,请进行扩展。

2 个答案:

答案 0 :(得分:11)

尝试这样的事情:

select article_id, count(tag_id) as common_tag_count
from articles_tags 
group by tag_id
where tag_id in (
    select tag_id from articles_tags where article_id = 2
) and article_id != 2
order by common_tag_count desc;

语法可能需要对MySQL进行一些调整。

或实际上有效的那个:; - )

SELECT at1.article_id, Count(at1.tag_id) AS common_tag_count
FROM articles_tags AS at1 INNER JOIN articles_tags AS at2 ON at1.tag_id = at2.tag_id
WHERE at2.article_id = 2
GROUP BY at1.article_id
HAVING at1.article_id != 2
ORDER BY Count(at1.tag_id) DESC;

答案 1 :(得分:2)

类似的东西:

SELECT a.* 
FROM articles AS a 
INNER JOIN articles_tags AS at ON a.id=at.article_id
INNER JOIN tags AS t ON at.tag_id = t.id
WHERE t.title = 'funny' OR t.title = 'goofy' OR t.title = 'silly' AND a.id != <article_id>
GROUP BY a.id
ORDER BY COUNT(a.id) DESC

只使用通常的索引,假设articles_tags的PK为(article_id,tag_id),而tags.title上的索引