Question

I have the following objects Company, User and Order (contains orderlines). User's place orders with 1 or more orderlines and these relate to a Company. The time period for which orders can be placed for this Company is only a week.

What I'm not sure on is where to place the orders array, should it be a collection of it's own containing a link to the User and a link to the Company or should it sit under the Company or finally should the orders be sat under the User.

Numbers wise I need to plan for 50k+ in orders.

Queries wise, I'll probably be looking at Orders by Company mainly but I would need to find an Order by Company based for a specific user.

Was it helpful?

Solution

1) For folks coming from the SQL world (such as myself) one of the hardest learn about MongoDB is the new style of schema design. In the SQL world, everything goes into third normal form. Folks come to think that there is a single right way to design their schema, because there typically is one.

In the MongoDB world, there is no one best schema design. More accurately, in MongoDB schema design depends on how the application is going to access the data.

2) Here are the key questions that you need to have answered in order to design a good schema for MongoDB:

  • How much data do you have?
  • What are your most common operations? Will you be mostly inserting new data, updating existing data, or doing queries?
  • What are your most common queries?
  • How many I/O operations do you expect per second?

What you're talking about here is modeling Many-to-One relationships:

  • Company -> User
  • User -> Order
  • Order -> Order Lines
  • Company -> Order

Using SQL you would create a pair of master/detail tables with a primary key/foreign key relationship. In MongoDB, you have a number of choices: you can embed the data, you can create a linked relationship, you can duplicate and denormalize the data, or you can use a hybrid approach.

The correct approach would depend on a lot of details about the use case of your application, many of which you haven't provided.

3) This is my best guess - and it's only a guess - as to a good schema for you.

a) Have separate collections for Users, Companies, and Orders

If you're looking at 50k+ orders, there are too many to embed in a single document. Having them as a separate collection will allow you to reference them from both the Company and the User documents.

b) Have an array of references to the Order documents in both the Company and the User documents. This makes the query "Find all Orders for this Company" a single-document query

c) If your query pattern supports it, you might also have a duplicate link from Orders back to the owning Company and/or User.

d) Assuming that the order lines are unique to the individual Order, you would embed the Order Lines in an array within the Order documents.

e) If your order lines refer back to individual Products, you might want to have a separate Product collection, and include a reference to the Product document in the order line sub-document

4) Here are some good general references on MongoDB schema design.

MongoDB presentations:

Here are a couple of books about MongoDB schema design that I think you would find useful:

Here are some sample schema designs:

Note that the "MongoDB in Action" book includes a sample schema for an e-commerce application, which is very similar to what you're trying to build -- I recommend you check it out.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top