Question

I am just starting out with MongoDB (Late to the party, I know...)

I am still trying to get 10+ years of relational DBing out of my head when thinking of a document design.

Lets say I have many users using many apps. Any user can use several apps, and any app can be used by any number of users.

In the login procedure I would like to access all the apps a user uses. In another procedure I would like to get all the users of a specific app.

Should I just have duplicate data? Maybe have an array of users in the App document and an array of apps in the user document? Does this make sense? Is this a conventional approach in document DBs?

Was it helpful?

Solution 2

As per your scenario, you need not have duplicate data. Since it's a many to many relationship and the data is going to keep changing, you need to use document reference instead of document embedding.

So you will have two collections:

app collection :

{
     _id : appId,
    app_name : "appname",
    // other property of app
    users : [userid1, userid2]

}

users collection:

{
      _id : userId,
      // other details of user
     apps: [appid1, appid2, ..]

}

As you mentioned you need to have array of users in app collection & array of apps in user collection.

When you are fetching data in the client, at first when the user logs in, you will get the array of app IDs from the user document.

Then again, with the app IDs you need to query for Apps details in the app collection.

This roundtrip will be there for sure as we are using references. But you can improve performance by caching the details & by having proper indexes.

This is conventional in mongodb for a many to many relationship

OTHER TIPS

Good question!

You have many to many scenario. In Mongo you can solve this problem in many ways: Using a lookup table like in SQL or having an array. What you should consider are indexes, same as in SQL, but this time you have more options. Since its a many to many scenario I would probably go with the lookup table. This is the most effective way to get users of an app and apps of a user. Array is not good for dynamic values especially if you need two array fields (app / user) while the app.users array field is going to change often. The downside is that you can "join" and will have to "select" data from two tables and do the "join" yourself but this shouldn't be an issue, especially since you can always cache the result (local caching in your application) and Mongo will return the result super fast if you will add index for the user field

{
_id: "<appID>_<userID>" ,
user: "<userID>"
}

_id indexes by default. Another index should be created for the "user" field then Mongo will load the btree into memory and you are all good.

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