For my blog, I want to incorporate my own commenting system without relying on the default wordpress commenting system. I need the comments module to utilize mongodb instead of mysql and the module needs support for the following:
- Threaded comments
- Comment Voting
- The votes on comments need to be aggregated per each comment author for the entire blog.
In this context, What is best way to represent the data in mongodb?
Just store the comments as you want them represented on your blog. You want threaded/nested comments? Then store them in a nested fashion:
postId: {
comments: [
{
id: "47cc67093475061e3d95369d" // ObjectId
title: "Title of comment",
body: "Comment body",
timestamp: 123456789,
author: "authorIdentifier",
upVotes: 11,
downVotes: 2,
comments: [
{
id: "58ab67093475061e3d95a684"
title: "Nested comment",
body: "Hello, this is a nested/threaded comment",
timestamp: 123456789,
author: "authorIdentifier",
upVotes: 11,
downVotes: 2,
comments: [
// More nested comments
]
}
]
},
{
// Another top-level comment
}
]
}
The postId
refers to the blog post to which the comments belong and has been used as the key (or _id
in MongoDB) of the document. Each comment has a unique id
, in order to vote or comment on individual comments.
To get the aggregated votes, you'll need to write map-reduce functions somewhere along these lines:
function map() {
mapRecursive(this.comments)
}
function mapRecursive(comments) {
comments.forEach(
function (c) {
emit(comment.author, { upVotes: c.upVotes, downVotes: c.downVotes });
mapRecursive(c.comments);
}
);
}
function reduce(key, values) {
var upVotes = 0;
var downVotes = 0;
values.forEach(
function(votes) {
upVotes += votes.upVotes;
downVotes += votes.downVotes;
}
);
return { upVotes: upVotes, downVotes: downVotes };
}
I haven't tested these functions and they don't check for null
values either. That's up to you :)