Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose – linking objects to each other without duplicating

I have a model "Category". Collection categories contains several objects. I also a have model "Post". Collection posts may contain a lot of objects with users' posts. "Post" object may relate to 1+ categories. How to link "Post" object to 1+ "Category"-objects without placing "Post"-object inside "Category"-object as subdocument? Certainly, I need to have an option to find all posts related to certain category.

One of the ways I can imagine is to store in "Post"-object obj_id of all categories which it's related to. Smth like this:

var postSchema = mongoose.Schema({
  title: String,
  description: String,
  category: [ObjectId],
  created_time: Number,
})

and add category later...

post.category.push(obj_id);

but is it really a mongoose-way? Which way is correct? Thanks.

P.S. I've also read about population methods in mongoose docs, may it be useful in my case? Still not completely clear for me what is this.

like image 374
Alex Shest Avatar asked Jun 21 '13 21:06

Alex Shest


1 Answers

Populate is a better tool for this since you are creating a many to many relationship between posts and categories. Subdocuments are appropriate when they belong exclusively to the parent object. You will need to change your postSchema to use a reference:

var postSchema = mongoose.Schema({
  title: String,
  description: String,
  category: [{ type: Schema.Types.ObjectId, ref: 'Category' }],
  created_time: Number,
});

You can add categories by pushing documents onto the array:

post.category.push(category1);
post.save(callback);

Then rehydrate them during query using populate:

Post.findOne({ title: 'Test' })
.populate('category') 
.exec(function (err, post) {
   if (err) return handleError(err);
   console.log(post.category); 
});
like image 87
mr.freeze Avatar answered Sep 28 '22 01:09

mr.freeze