Rohit Luthra
Rohit Luthra

Reputation: 1286

MongoDB/Mongoose- How to use nested objects/documents or subdocuments

I am creating simple RestApi using MongoDB, Mongoose, Node.js, Express.js and In which there will be multiple users and many more users can sign up and there will be an entry for each user in user collection(database). And my user Schema(users.js) will be like

var mongoSchema = mongoose.Schema;
var userSchema ={
    mobileno: {
        type:String
    },
    firstname: {
        type:String
    },
    lastname: {
        type:String
    },
    facebookid: {
        type:String
    },
    userimage: {
        type:String
    }
}
module.exports = mongoose.model('user', userSchema);

Now each user can save one or more products as follows

enter image description here

Now which one would be the best solution:

  1. Should I use separate collection (products collection with one field like mobile no for reference)
  2. Or Should I use subdocument or nested objects

My personal choice is second one but I am new in MongoDB and Mongoose environment. Please help me what I need to change in users schema.

Upvotes: 2

Views: 726

Answers (4)

Rohit Luthra
Rohit Luthra

Reputation: 1286

After reading existing stack overflows answers I think following approach would be right. Please suggest or correct me if I am wrong.

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var productSchema = new Schema{
 prod_name: {
    type:String
 },
 prod_cost: {
    type:String
 }
}

var userSchema = new Schema{
  mobileno: {
    type:String
  },
  firstname: {
    type:String
  },
  lastname: {
    type:String
  },
  facebookid: {
    type:String
  },
  userimage: {
    type:String
  },
  products: [productSchema]
}


module.exports = mongoose.model('user', userSchema);
module.exports = mongoose.model('products', productSchema);

Upvotes: 0

Amulya Kashyap
Amulya Kashyap

Reputation: 2373

You can do it like this :

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema{
  mobileno: {
    type:String
  },
  firstname: {
    type:String
  },
  lastname: {
    type:String
  },
  facebookid: {
    type:String
  },
  userimage: {
    type:String
  }
}

var productSchema = new Schema{
 _user:{type: Schema.ObjectId, ref: 'user'}
 prod_name: {
    type:String
 },
 prod_cost: {
    type:String
 }
}
module.exports = mongoose.model('user', userSchema);
module.exports = mongoose.model('products', productSchema);

You can reference user to product table (i,.e, just like joins in mysql)

And populate while fetching the profile :

Models.products.find(criteria, projection, options).populate([
    {path: '_user', select: 'prod_name, prod_cost'},
]).exec(callback);

Thanks & Regards

Upvotes: 1

Manish Singh
Manish Singh

Reputation: 538

I think, the better way is other way around.

  • Save the product as a collection and user as another collection.
  • In product collection, save the reference of user.

Then use populate() to populate user in product, if you want.

Upvotes: 0

hyades
hyades

Reputation: 3170

The second choice is generally preferred. The schema for the product key would look like -

products: [productname: String, productdesc: String, ]

However, in some cases the first option to create a separate product collection makes more sense. This would happen if the collection depends on some external source and is fairly dynamic in nature. Here you would find it easier to update at one place rather than a lot of places. In this case, you can have a schema like

products: [productSchema]

Here for getting the product details, you would need to do $lookup operations

Upvotes: 0

Related Questions