Votes (Ugly)

Poll

{
    _id: 1,
    title: "Do you like Brazil?",
    options: ["Yes", "More or Less", "Perhaps"],
}

Votes

{
    userId: 1,
    pollId: 1,
    vote: "Yes",
}
Votes (Bad)

Poll

{
    _id: 1,
    title: "Do you like Brazil?",
    options: ["Yes", "More or Less", "Perhaps"],
    votes: [
        userId: 1,
        vote: "Yes",
    ]
}
Votes (Good)

Poll

{
    _id: 1,
    title: "Do you like Brazil?",
    options: ["Yes", "More or Less", "Perhaps"],
    votes: [
        userId: 1,
        vote: "Yes",
    ],
    totalVotes: 1,
    votes: [1, 0, 0],
}

Post && Comments

http://www.flickr.com/photos/somewhatfrank/251789400
Post and comments (Ugly)

Post

{
    _id: 3,
    title: "This is a blog post",
    content: "Here is where the text goes ...",
}

Comments

{
    _id: 1,
    postId: 3,
    name: "César Rodas",
    email: "saddor@gmail.com",
    comment: "Nice post",
}
Post and comments (Bad)
// Posts
{
    _id: 3,
    title: "This is a blog post",
    content: "Here is where the text goes ...",
    comments: [
        {
            name: "César Rodas",
            email: "saddor@gmail.com",
            comment: "Nice post",
        },
        ..., 
        {
            name: "David Maldonado",
            email: "saddor@gmail.com",
            comment: "+1",
        },
    ]
}
Post and comments (Good)
// Posts
{
    ...
    commentsTotal: 11,
    commentsPerDocument: 10,
}
// Comments
{
    _id: 3,
    postId: 3,
    comments: [
        {
            name: "César Rodas",
            email: "saddor@gmail.com",
            comment: "Nice post",
        },
        ...
    ]
}
// Comments
{
    _id: 4,
    postId: 3,
    comments: [
        {
            name: "David Maldonado",
            email: "saddor@gmail.com",
            comment: "+1",
        },
        ...
    ]
}

Post && Tags

http://www.flickr.com/photos/maguisso/431211896
Post and comments (Good)
//Post
{
    title:"yet another post",
    body: "yet another body",
    tags: ["one tag", "another tag", "tag"],
}
Post and tags (Ugly)
//Post (tags and timestamp)
{
    title:"yet another post",
    body: "yet another body",
    tags: {
        "one tag": ts, 
        "another tag": ts, 
        "tag":ts
    }
}
Post and tags (Ugly)
Post and tags (Ugly)
db.posts.ensureIndex({tags:1})
db.posts.find({"tags.foobar": {"$gt":0}}).explain()
{
        "cursor" : "BasicCursor",
        "nscanned" : 14216,
        "nscannedObjects" : 14216,
        "n" : 64,
        ...
}
Post and tags (Good)
//Post
{
    title:"yet another post",
    body: "yet another body",
    tags: [
        {tag: "one tag", ts: ts}, 
        {tag: "another tag", ts: ts}, 
        {tag:"tag", ts: ts}
    ]
}
Post and comments (Good)
db.posts.ensureIndex({tags.tag:1})
db.posts.find({"tags.tag": "foobar"}).explain()
{
        "cursor" : "BtreeCursor tags.tag_1",
        "nscanned" : 64,
        "nscannedObjects" : 64,
        "n" : 64,
        ...
}

Autoincrement

Autoincrement (Ugly)
function getNextId(collection) {
    return db[collection].count() + 1;
}

db.post.save({
    _id: getNextId("post"),
    title: "something here",
});
Autoincrement (Good)

function getNextId(col) {
    return db.runCommand({
        findAndModify:"autoincrement", 
        query:{_id:col}, 
        new:true, 
        update:{$inc:{"lastId": 1}}, 
        upsert:true
    })['value']['lastId'];
}
Conclusion

Thanks!

Feedback: http://joind.in/3580

Questions?

http://cesarodas.com/mongosp2011/