J Cole Morrison
J Cole Morrison

J Cole Morrison

Lead Engineer @Fieldboom, former Techstars Hackstar, AWS Solutions Architect, and Headmaster at awsdevops.io

Practical and Professional Devops with AWS, Docker, and Node.js

A Quick, Vital Tip for New MongoDB'ers

Posted by J Cole Morrison on .

A Quick, Vital Tip for New MongoDB'ers

Posted by J Cole Morrison on .

mongodb

This is aimed at people interested in the MEAN stack and have a need to sprinkle some relational functionality onto Mongo. If you need to do this USE MONGOOSE.JS.

So this is pretty simple, but at first (especially if you haven't done a lot with databases) it can be counter intuitive.

Don't Nest Collections.

For example, if you have a user document and they have "books" don't do it like this:

> db.users.find({ email: "me@jcolemorrison.com"})

{
    _id: ObjectId("asdfn1238nakljx"),
    firstname: "Cole",
    lastname: "Morrison",
    email: "me@jcolemorrison.com",
    books: [
        {
            title: "Ender's Game",
            author: "Orson Scott Card",
            thoughts: "Awesome book, bad movie."
        },
        {
            title: "The Way of Kings",
            author: "Brandom Sanderson",
            thoughts: "Storm you all!"
        }
    ]
}

I know. I know. I know. This looks like it makes sense. And it does. BUT. MongoDB gives no easy way to sort, modify, and traverse through nested collections. So let's say you want to change the "thoughts" on "Ender's Game." Here's the fun query you have to type out:

> db.users.update(
    { 
        "email": "me@jcolemorrison.com",
        "book.title": "Ender's Game"
    },
    { 
        $set: { 
            'books.$.thoughts': "My thoughts exactly"  }
    }
);

Oh what? You forgot to add a unique ID to each book? Too bad. This is how you'd do it. Okay okay, this isn't TOO bad. But I'll show you what is.

Client: Can we add a "Date Added" field to all of the books that users have?

Mwahahaha. Try it. Oh that's right. YOU CAN'T. Not without writing a script to handle it or doing it manually.

Client: Well, could we rename the "thoughts" field to "description" ?

BAHAHAHAHA. TRY IT. OH YOU CAN'T. Mongo won't let you update all items in an array simultaneously.

Let's pretend that you HAD added a date field to the books before you'd inserted them. And then let's pretend that you want to change all books in a user's collection that we're added AFTER 4/1/14. You can't.

How I felt after wasting who knows how much of my life on nested collections

How You Should Do it

When you need to give a user "books" just make a whole new collection. So just like you have a "users" collection (db.users.find()) you'd have a "books" collection (db.books.find()). Now let's revisit the above. So a document would look like this:

> db.books.findOne()

{
    _id: ObjectId("somerandomthingofids"),
    userId: "idOfUserWhoOwnsThisBook",
    title: "Some Title",
    author: "Some Author",
    thoughts: "Some Thoughts about book"
}

Client: Can we add a "Date Added" field to all of the books that users have?

> db.books.update({},
    { $set: { "dateAdded": 1 }},
    { multi: true })

Client: Well, could we rename the "thoughts" field to "description" ?

> db.books.update({},
    { $rename: { "thoughts": "description" }},
    { multi: true })

And done.

COLLECTION ALL THE THINGS

Hopefully this helps some other developer from wasting hours upon hours trying to push and pull nested documents.

J Cole Morrison

J Cole Morrison

http://start.jcolemorrison.com

Lead Engineer @Fieldboom, former Techstars Hackstar, AWS Solutions Architect, and Headmaster at awsdevops.io

J Cole Morrison

J Cole Morrison

Lead Engineer @Fieldboom, former Techstars Hackstar, AWS Solutions Architect, and Headmaster at awsdevops.io

Practical and Professional Devops with AWS, Docker, and Node.js

Free 10 Part Video Series on Docker and AWS

The Hitchhiker's VIDEO Guide to AWS ECS and Docker The Hitchhiker's VIDEO Guide to AWS ECS and Docker

An Exploration of Deploying Docker based Apps and Services to AWS EC2 Container Service.

Checkout the FREE 10 Part Video Series