In many database-based projects you have to show your visitors that this “thing” is similar to this other one. For example, this blog post is similar to this other one. That’s a crucial functionnality and at first sight it’s looks easy to create.
The landscape
let’s start with this basic example :
In a blog, a “blog_post” has many “tag”. These relations are stored in a “blog_post_tag” table. When a blog post is displayed, we want to show the list of similar post to the current blog_post. Our “blog_post_tag” table just store “blog_post_id” and “tag_id“.
The first train of thought
I wanted to get all blog post that have the same associated tag. But, in this database-relation context “the same” may only mean only one of them. Quite annoying. So i finally get something that worked, and that was based on this kind of algorythm:
blogPostTags = $myBlogPost->getTags
postList = array()
foreach(blogPostTags as currentTag)
tempPostList = getAllBlogPostByTag(currentTag)
postList = array_merge(postList, array_diff(tempPostList,postList)
endforeach
Quite awfull isn’t it ? after two hours spent on something else and got back to home and discussed with friends (and whatever you want. Who said IT guy do not have a social life ?!) i just looked back at this problem and finally wrote this :
The proper way
SELECT COUNT(tag_id) as similarity, blog_post_id FROM blog_post_tag
WHERE tag_id IN (
SELECT tag_id FROM blog_post_tag WHERE blog_post_id = ?
)
GROUP BY blog_post_id
And that’s all. This SQL code gives you how many common tag you have between all the post that have at least on tag in common with a specific blog_post (replace ‘?’ by the correct value). Now just have to write it whith the Doctrine syntax ;-)
Conclusion
Just remember : when it sucks, just take a break !
Tags:
devloppement,
mysql,
tips