2

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.

Rohit Luthra
  • 1,256
  • 17
  • 27

4 Answers4

1

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

Amulya Kashyap
  • 2,333
  • 17
  • 25
0

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

hyades
  • 3,110
  • 1
  • 17
  • 36
0

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.

Manish Singh
  • 518
  • 3
  • 13
  • Seems correct approach because this is exactly the first idea which came in mind when I got this task. – Rohit Luthra Nov 18 '16 at 09:20
  • But this approach becomes lengthy because when I will delete any user so also I need to delete its saved products by running separate function or is there any cascade delete like option. – Rohit Luthra Nov 18 '16 at 09:28
  • yes. you have this option. Please have a look http://stackoverflow.com/questions/30255638/how-to-cascade-delete-using-mongoose-remove-middleware – Manish Singh Nov 18 '16 at 09:45
0

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);
Rohit Luthra
  • 1,256
  • 17
  • 27