Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB Schema optimization for saving users contacts

I want to design a schema for storing Contacts of Users.

Here are my existing schemas:

User Schema

_id : ObjectId("5c53653451154c6da4623a77"),
name : “something”,
email : “something”,
password : “something”,

Profile Schema

"_id" : ObjectId("5c53653451154c6da4623a88"),
user_id - ref
mobile : “something”,
company” : “something”,
designation : “something”,
website : “something”,
social: {
    youtube: {
        type: String
    },
    twitter: {
        type: String
    },
    facebook: {
        type: String
    },
    linkedin: {
        type: String
    },
    instagram: {
        type: String
    }
}

I can think of two approaches to the Contact schema but both have some cons:

First approach

"_id" : ObjectId("5c53653451154c6da4623a99"),
user_id - ref,
"contacts": [
   {
    name : “something”,
    company : “something”,
    designation : “something”,
    website : “something”,
    social: { something },
    mobile : “something”
   },
   {
    name : “something”,
    company : “something”,
    designation : “something”,
    website : “something”,
    social: { something },
    mobile : “something”
    },
    ...
]

The problem with the above structure is that when the User updates their Profile the Contact fields can not get the updated value. But in this approach, it is easy to query and retrieve all Contacts of a particular User and send the response back.

Second approach

"_id" : ObjectId("5c53653451154c6da4623a99"),
user_id : ref,
contacts: [
    profile_id,
    profile_id,
    profile_id,
    profile_id,
    profile_id,
    profile_id,
    ...
]

In this structure Contacts have the updated User value when the User updates their Profile. But the problem here is while querying I have to fetch the profile id from the Contact schema, then query the Profile schema and return the value to the client as a response.

What happens when there are 30K-50K contacts - do I need to query the DB 50K times? Or is there a better approach?

Building on node.js, using mongoose.

like image 611
Aditya Pranav Avatar asked Nov 20 '25 21:11

Aditya Pranav


2 Answers

Basically you have a scenario where relational database will be required. But You can also achive this in mongo .

You need to use populate of mongoose. With your second approach. Where you storing profile ids.

User.find({_id: '5c53653451154c6da4623a77'}).populate({
path:'profiles',
options: {
    limit: 10,
    skip: 0
}}).exec();

Mongoose populate

This query will return related profiles. If you have data like 50K. You must limit the data in one request.

NOTE: Mongodb limit for per document is 16mb. It is not possible to store that much data.

So, Just rethink your database.

like image 180
Arpit Yadav Avatar answered Nov 23 '25 11:11

Arpit Yadav


If I understand you correctly I think you've correctly identified some pros/cons of each option. Now you have to decide what makes sense for your specific case. Option 1 will be easy for fetching but tedious for updating and keeping in sync with Profiles. Option 2 has more normalized data and will be better for updating but will require more queries to retrieve. So you have to ask yourself some questions.

  • How important is having normalized data to you?
  • How will the size of your Profile vs Contact schemas compare? Will you have significantly more Profiles? Significantly less? Orders of magnitude?
  • What happens more often - that someone updates their profile or that someone queries for contacts? How much more? Orders of magnitude?
  • To dive deeper into your last two answers - do some estimates, even rough ones if you have to, and then do some math to see what might make more sense.

For example, if you will have 10,000 contacts per user then option #1 will give you a much larger document that can gather all contacts and profiles in a single query. If your users only update their profiles say, on average, once a month but you need to query contacts several times a day this might be the better option. However, if you have users who like to update their profile daily and you need to query contacts maybe once a week then option #2 could make more sense.

At the end of the day it's a design choice that is very specific to your scenario. Good luck!

like image 43
Ashley Avatar answered Nov 23 '25 11:11

Ashley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!