MongoDB Schema Design - Many small documents or fewer large documents?

Andre picture Andre · Jun 14, 2010 · Viewed 25.9k times · Source

Background
I'm prototyping a conversion from our RDBMS database to MongoDB. While denormalizing, it seems as if I have two choices, one which leads to many (millions) of smaller documents or one which leads to fewer (hundreds of thousands) large documents.

If I could distill it down to a simple analog, it would be the difference between a collection with fewer Customer documents like this (in Java):

class Customer {
    private String name;
    private Address address;
    // each CreditCard has hundreds of Payment instances
    private Set<CreditCard> creditCards;
}

or a collection with many, many Payment documents like this:

class Payment {
    private Customer customer;
    private CreditCard creditCard;
    private Date payDate;
    private float payAmount;
}

Question
Is MongoDB designed to prefer many, many small documents or fewer large documents? Does the answer mostly depend on what queries I plan on running? (i.e. How many credit cards does customer X have? vs What was the average amount all customers paid last month?)

I've looked around a lot but I didn't stumble into any MongoDB schema best practices that would help me answer my question.

Answer

Gates VP picture Gates VP · Jun 22, 2010

You'll definitely need to optimize for the queries you're doing.

Here's my best guess based on your description.

You'll probably want to know all Credit Cards for each Customer, so keep an array of those within the Customer Object. You'll also probably want to have a Customer reference for each Payment. This will keep the Payment document relatively small.

The Payment object will automatically have its own ID and index. You'll probably want to add an index on the Customer reference as well.

This will allow you to quickly search for Payments by Customer without storing the whole customer object every time.

If you want to answer questions like "What was the average amount all customers paid last month" you're instead going to want a map / reduce for any sizeable dataset. You're not getting this response "real-time". You'll find that storing a "reference" to Customer is probably good enough for these map-reduces.

So to answer your question directly: Is MongoDB designed to prefer many, many small documents or fewer large documents?

MongoDB is designed to find indexed entries very quickly. MongoDB is very good at finding a few needles in a large haystack. MongoDB is not very good at finding most of the needles in the haystack. So build your data around your most common use cases and write map/reduce jobs for the rarer use cases.