How do i add/update ObjectId array in a collection using MongoDB(Mongoose)?

12,112

What you want is called "population" in Mongoose (see documentation), which basically works by storing references to other models using their ObjectId.

When you have a Post instance and a Comment instance, you can "connect" them like so:

var post    = new Post(...);
var comment = new Comment(...);

// Add comment to the list of comments belonging to the post.
post.commentIds.push(comment); // I would rename this to `comments`
post.save(...);

// Reference the post in the comment.
comment.post = post;
comment.save(...);

Your controller would look something like this:

exports.postComment = function(req,res) {
  // XXX: this all assumes that `postId` is a valid id.
  var comment = new Comment({
    content : req.body.content,
    post    : req.params.postId,
    user    : req.user._id
  });
  comment.save(function(err, comment) {
    if (err) return res.send(err);
    Post.findById(req.params.postId, function(err, post) {
      if (err) return res.send(err);
      post.commentIds.push(comment);
      post.save(function(err) {
        if (err) return res.send(err);
        res.json({ status : 'done' });
      });
    });
  });
};
Share:
12,112

Related videos on Youtube

Keon Kim
Author by

Keon Kim

Updated on June 04, 2022

Comments

  • Keon Kim
    Keon Kim almost 2 years

    This is What I want as a final result. I have no idea how to update array of indexes.

    enter image description here

    my Schema is built using mongoose

    var postSchema  = new Schema({
        title: {type:String},
        content: {type:String},
        user:{type:Schema.ObjectId},
        commentId:[{type:Schema.ObjectId, ref:'Comment'}],
        created:{type:Date, default:Date.now}
    });
    
    
    var commentSchema  = new Schema({
        content: {type:String},
        user: {type:Schema.ObjectId},
        post: {type:Schema.ObjectId, ref:'Post'}
        created:{type:Date, default:Date.now}
    });
    

    My controllers are:

    // api/posts/
    exports.postPosts = function(req,res){
        var post = new Post({
            title: req.body.title,
            content: req.body.content,
            user: req.user._id
        });
        post.save(function(err){
            if(err){res.send(err);}
            res.json({status:'done'});
        });
    };
    
    
    // api/posts/:postId/comments
    exports.postComment = function(req,res){
        var comment = new Comment({
            content: req.body.content,
            post: req.params.postId,
            user: req.user._id
        });
        comment.save(function(err){
            if(err){res.send(err);}
            res.json({status:'done'});
        });
    };
    

    Do I need to use a middleware? or do i need to do something in controller?

  • chridam
    chridam almost 9 years
    On the line post.commentIds.push(comment); shouldn't it be post.commentIds.push(comment._id);?
  • robertklep
    robertklep almost 9 years
    @chridam that's not necessary, Mongoose is smart :-)
  • J.Correa
    J.Correa over 6 years
    the problem with this is if postId doesn't exists will trigger error but the comment will be saved anyway
  • robertklep
    robertklep over 6 years
    @J.Correa true, if the post doesn't exist you'd have to clean up the just-saved comment, or work the other way around: first find the post, and if it exists, save and add the comment.
  • J.Correa
    J.Correa over 6 years
    yes, and you can use chain promises for that work, it's something that i'am just doing right now :o
  • robertklep
    robertklep over 6 years
    @J.Correa I don't think Mongoose supported promises back in 2015 ;D