Which is the best design for a MongoDB database model?

Hi !

I feel like the MVP of my current database needs some design changes. The number of users is growing quite fast and we are having bad performances in some requests. I also want to get rid of all the DBRef we used.

Our current model can be summarized as follow :

  • A company can have multiple employees (thousands)
  • A company can have multiple teams (hundreds)
  • An employee can be part of a team
  • A company can have multiple devices (thousands)
  • An employee is affected to multiple devices

Our application displays in different pages :

  • The company data
  • The users
  • The devices
  • The teams

I guess I have different options, but I’m not familiar enough with MongoDB to make the best decision.

Option 1

Do not embed and use list of ids for one to many relationships.

// Company document
{
    "companyName": "ACME",
    "users": [ObjectId(user1), ObjectId(user2)],
    "teams": [ObjectId(team1), ObjectId(team2)],
    "devices": [ObjectId(device1), ObjectId(device2)]
}

// User Document
{
    "userName": "Foo",
    "devices": [ObjectId(device2)]
}

// Team Document
{
    "teamName": "Foo",
    "users": [ObjectId(user1)]
}

// Device Document
{
    "deviceName": "Foo"
}

Option 2

Embed data and duplicate informations.

// User Document
{
    "companyName": "ACME",
    "userName": "Foo",
    "team": {
        "teamName": "Foo"
    },
    "device": {
        "deviceName": "Foo"
    }
}

// Team Document
{
    "teamName": "Foo"
    "companyName": "ACME",
    "users": [
        {
            "userName": "Foo"
        }
    ]
}

// Device Document
{
    "deviceName": "Foo",
    "companyName": "ACME",
    "user": {
        "userName": "Foo"
    }
}

Option 3

Do not embed and use id for one to one relationship.

// Company document
{
    "companyName": "ACME"
}

// User Document
{
    "userName": "Foo",
    "company": ObjectId(company),
    "team": ObjectId(team1)
}

// Team Document
{
    "teamName": "Foo",
    "company": ObjectId(company)
}

// Device Document
{
    "deviceName": "Foo",
    "company": ObjectId(company),
    "user": ObjectId(user1)
}

MongoDB recommends to embed data as much as possible but I don’t think it can be possible to embed all data in the company document. A company can have multiple devices or users and I believe it can grow too big.

I’m switching from SQL to NoSQL and I think I haven’t figured it out by myself yet !

Thanks !

Hi @Aurelien_Audelin, welcome to the community. Glad to have you here.

Embed everything or reference everything are two extremes in schema design process. It doesn’t have to be one or the other. You could choose to be somewhere in between by utilizing extended reference pattern, subset pattern and outlier pattern, based on your application’s query patterns.

Here are some other patterns that may come in handy in your schema design process. Hope this helps. Let us know if you have any questions.

Thanks,
Mahi

1 Like