2011-08-29 59 views
3

我有一个艺术网站。我现在需要展示相关的艺术作品。我有3个表:多对多关系标签匹配?

art_info    : art_id, title 
art_tag_relationship : art_id, tag_id 
art_tags    : tag_id, tag (in text) 

我试图让相关技术通过最相关的标签匹配排序的给定的一件艺术品。

所以现在可以说我有5个艺术品与标签

艺术#1标签:红色,蓝色,绿色,黄色
艺术#2标签:红色,橙色,紫色,黑色,黄色,蓝色
艺术#3标签:红
艺术#4标签:蓝色,绿色
艺术#5标签:白色,棕色

所以现在我想获得最相关的艺术作品,以艺术#1的顺序最匹配到最少匹配。我希望得到这样的

相关技术,以#1的结果:

  • 最佳匹配=艺术#2(因为它匹配的3个标签)
  • 第二节比赛=艺术#4(因为它匹配2个标签)
  • 第3场比赛=第3场比赛(因为它匹配了1个标记)
  • 不显示第5场比赛,因为没有找到比赛。

我正在考虑使用foreach语句,一旦我得到艺术#1的标签,但这似乎效率低下。

这里是我用来获取艺术#标签1

SELECT art_info.art_id, art_info.title 
FROM art_info 
INNER JOIN art_tag_relationship ON art_info.art_id = art_tag_relationship.art_id 
WHERE art_tag_relationship.art_id = '1' 

所以现在查询一次我从艺术#1的4个标签,我如何才能拥有最最艺术相关标签?

谢谢你的时间和使用大脑。

编辑:概念似乎是,通过art_tag_relationship - > art_tags获取art#tag的标签,然后从art_tag_relationships获取art_id,其中tag_id与art_tag_relationships中art_id#1的找到标签相同。

回答

1

您可以选择最相关的艺术作品,给出另一个art_id。

SELECT 
    ai.art_id, 
    ai.title 
    count(DISTINCT r2.tag_id) as relevance 
FROM art_tag_relationship r1 
INNER JOIN art_tag_relationship r2 ON (r1.tag_id = r2.tag_id 
            AND r1.art_id <> r2.art_id) 
INNER JOIN art_info ai ON (r2.art_id = ai.art_id) 
WHERE r1.art_id = '1' -- this is the art_id results should be related to. 
GROUP BY ai.art_id 
ORDER BY relevance DESC 
+0

工程就像一个魅力。绝对美丽的谢谢你!我从来没有见过使用过的<>。我会更多地阅读这个。再次感谢! – Darius

+0

@Darius“<>”表示不等于。 – Johan

+0

嘿约翰,我有点过激,它似乎在工作,但是当我测试它时,结果发现它计算了与匹配标签完全不同的东西。我用4个标签搜索了一个art_id,它给了我9的相关性。我不明白它在这个点上的计数是什么,因为具有最高相关性的艺术没有与我比较的艺术相同的标签。有任何想法吗?我怀疑它做的次数是多少张艺术照片使用同一个标签的次数,但不包括它制作的匹配数量。 – Darius

0

既然你正在看一件艺术品是art_id = 1000

SELECT 
    art_info.art_id, 
    art_info.title 
    count(*) as Cnt 
FROM 
    art_tag_relationship A1, 
    art_tag_relationship A2, 
    art_info 
WHERE 
    A1.art_id = 1000 
    AND 
    A1.tag_id = A2.tag_id 
    AND 
    A2.art_id = art_info.art_id 
GROUP BY 
    art_info.art_id 
ORDER BY 
    Cnt DESC 

(未经测试)

从理论上讲,它会与所有的艺术,你是看标签的开始。然后它会展开以匹配其他艺术作品的所有相关标签。然后,它将根据生成的art_id对其进行分组,并且缩减到每个组中的记录数应等于匹配的标记数,然后对其进行排序。

玩过这个概念,并更新您的文章,一旦你有一个工作查询。

+0

使用这个概念。这意味着当一个成员提交一些标签时,我会运行一个foreach语句来分隔每个单词,检查它是否存在于标签中。如果存在,请使用现有的tag_id链接到art_tags_relationship表中,如果该单词不存在,请将其输入到art_tags表中? – Darius

+0

此外,它似乎并没有像我们预期的那样做,找到标签然后找到与其匹配的其他标签。它使它坚持art_id = 1000.所以它只给我art_id 1000的结果,并不会显示任何其他art_id。 – Darius

+0

-1使用隐式连接。 – Johan