MongoDB Schema optimization for saving users contacts

mongodb schema example
mongodb schema design
mongodb social network schema example
mongodb storage optimization
mongodb schema design for real-world examples
mongodb user model
mongodb index
mongodb query optimization

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.

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.

MongoDB Schema optimization for saving users contacts, I want to design schema for storing contacts of users. Here my schema designs: User Schema _id : ObjectId("5c53653451154c6da4623a77"),� For example, a schema designed to hold user contact information may need to be updated to include new methods of communication as they become popular, such as Twitter or Skype. You can use MongoDB’s flexible schema model, which supports differently shaped documents in the same collection, to gradually update your collection’s schema.

How to Optimize Performance of MongoDB, For example, you can have a database for users and another for posts. So if a user makes a post it is recorded with user id. Users schema ? 1. Note. MongoDB supports draft 4 of JSON Schema, including core specification and validation specification, with some differences.See Extensions and Omissions for details.. For more information about JSON Schema, see the official website.

There are 2 schemas one is for the user and another for orders. One user can create multiple orders like your contacts.

user-

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const bcrypt = require("bcryptjs");

const userSchema = new Schema(
  {
    firstName: {
      trim: true,
      type: String,
      required: [true, "firstName is required!"],
      validate(value) {
        if (value.length < 2) {
          throw new Error("firstName is invalid!");
        }
      }
    },
    lastName: {
      trim: true,
      type: String,
      required: [true, "lastName is required!"],
      validate(value) {
        if (value.length < 2) {
          throw new Error("lastName is invalid!");
        }
      }
    },
    email: {
      unique: [true, "Email already registered"],
      type: String,
      required: [true, "Email is required"]
    },
    password: {
      trim: true,
      type: String,
      require: [true, "Password is required"],
      validate(value) {
        if (value.length < 6) {
          throw new Error("Password should be atleast 6 characters");
        }
      }
    },
    mobile: {
      trim: true,
      unique: [true, "Mobile Number already available"],
      type: String,
      required: [true, "Mobile Number is required"],
      validate(value) {
        if (value.length !== 10) {
          throw new Error("Mobile Number is invalid!");
        }
      }
    },
    gender: {
      trim: true,
      type: String,
      enum: [
        "Male",
        "Female"
      ],
      required: [true, "Password is required"],
    },
    dob: {
      trim: true,
      type: Date,
      required: [true, "DOB is required"],
    },
    Address: {
      address: {
        trim: true,
        type: String,
        require: [true, "Owner Address is required"]
      },
      city: {
        trim: true,
        type: String,
        require: [true, "Owner Address City is required"]
      },
      state: {
        trim: true,
        uppercase: true,
        type: String,
        require: [true, "Owner Address State is required"]
      },
      pin: {
        trim: true,
        uppercase: true,
        type: Number,
        require: [true, "Owner Address Pin is required"],
        validate(value) {
          if (!(value >= 100000 && value <= 999999)) {
            throw new Error("Pin is invalid!");
          }
        }
      }
    }
  },
  {
    timestamps: true
  }
);

const Users = mongoose.model("Users", userSchema);

module.exports = Users;

Order-

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const orderSchema = new Schema({
  userId: {
    trim: true,
    type: Schema.Types.ObjectId,
    ref: "users",
    required: [true, "User ID is required"]
  },
  dateOfOrder: {
    trim: true,
    type: Date,
    required: [true, "Date of Order is required"],
  },
  dateOfMeasurement: {
    trim: true,
    type: Date,
  },
  dateOfTrail: {
    trim: true,
    type: Date,
  },
  dateOfDelivery: {
    trim: true,
    type: Date,
  },
},


  {
    timestamps: true
  });

const Orders = mongoose.model("Orders", orderSchema);

module.exports = Orders;

Schema Design for Social Inboxes in MongoDB, When a user sends a message, it is simply saved to the inbox collection. data model to further optimize this design to be even more efficient. MongoDB performance comes from good concepts, organization, and data distribution. We are going to list some tips to optimize MongoDB. This is not an exhaustive or complete guide, as there are many variables. But this is a good start. Optimize MongoDB Keep documents simple. MongoDB is a schema-free database.

The problem you have is actually why mongodb is not the best choice for this scenario. Your data is relational, but you are using a non-relational database.


But for your situation there are some steps to make it better:

First approach

You can choose the first approach and when a user data is updated, also update all contacts. Easier query but hard to keep data in sync.

Second approach

Or you can choose the second approach, but instead of just saving the ref_id also save the contact name (the field is mostly gonna be used for querying). this way it would be easier to keep the data in sync and if search is done by name, you could just do a normal find.

Data Modeling Introduction — MongoDB Manual, Embedded documents capture relationships between data by storing related data in a single document structure. MongoDB Both the ``contact`` document. Most of the developers who have worked with relational databases know the importance of predictability of the data models or schema. Therefore, MongoDB introduced document validation from version 3.2. Let's see how to add validation rules in MongoDB collections. Suppose, you have a collection of users which have the following types of documents.

Optimize Query Performance — MongoDB Manual, Scanning an index is much faster than scanning a collection. The indexes structures are smaller than the documents reference, and store references in order. A number of factors can negatively affect MongoDB performance - inappropriate schema design, improper or no indexing, inadequate hardware, replication lag, poor query design. In this blog, we’ll take a look at these different factors and provide tips and tricks to optimize performance.

Time Series Data and MongoDB: Part 2 – Schema Design Best , Can it be simply restored from a backup when you need it, or does it need to be online and accessible to users in real time as an active archive for� Most MongoDB driver clients will include the _id field and generate an ObjectId before sending the insert operation to MongoDB; however, if the client sends a document without an _id field, the mongod will add the _id field and generate the ObjectId.

Data Model Examples and Patterns — MongoDB Manual, Describes one method for supporting keyword search by storing keywords in an array in the same document as the text field. Combined with a multi-key index, this� One trade off for using this schema is having to perform a second query to get details about the Parts for a Product. (But hold that thought until we get to denormalizing in part 2.) As an added bonus, this schema lets you have individual Parts used by multiple Products, so your One-to-N schema just became an N-to-N schema without any need for

Comments
  • will there multiple contacts of one user?
  • User Schema and Profile Schema should be the same.
  • No, it is like one user is saving contacts of another user in the contact array and so on. He can save as much as he wants.
  • User schema is here basically for login. Rest user have to create their own profile, and save contact (which is profile) of other users.
  • You should use one document for one contact and ref by userId.(Who saved it)
  • No, it is not same as mine, though I have one question which will probably solve my problem: How are you going to fetch the Profile info of all users who placed an order? Like there are 50K users who placed the order, and you have to show their profile, all the info that is in the user schema?
  • Then you will have to use aggregate in mongodb
  • You will fetch all orders and groupby by userid and fetch users, who placed orders.
  • yeah, but my project is too heavy and complicated.
  • Okay, no problem, just clear me one thing: so while fetching users, I have to query DB the same number of times as the count of the user?