Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove embedded scheme document in mongoose?

Having a problem with like removal My schema

/**
* Article Schema
 */
var Comments = new Schema({
    body: { type : String, default : '' },
    user: { type : Schema.ObjectId, ref : 'User' },
    createdAt: { type : Date, default : Date.now }
})
var Likes = new Schema({
    user: { type : Schema.ObjectId, ref : 'User' },
    createdAt: { type : Date, default : Date.now }
  })

var ArticleSchema = new Schema({
  title: {type : String, default : '', trim : true},
  body: {type : String, default : '', trim : true},
  geo: {type: [Number], set: setTags},
  user: {type : Schema.ObjectId, ref : 'User'},
  comments: [Comments],
  likes: [Likes],
  tags: {type: [], get: getTags, set: setTags},
  image: {type:String, default : ''},
  createdAt  : {type : Date, default : Date.now}
})

And I want to make like/unlike functionality, adding like works but removing simply doesnt change the document. Controller:

exports.like = function (req, res) {
var article = req.article
var user = req.user
Article.getArticleByWithLikesByUserId(req.user.id, function(err, articles) {
    console.log(articles);
    if(!articles.length){

      console.log('adding like',new Date);
      article.addLike(user, function (err) {
        if (err) return res.render('500')
        res.redirect('/articles/'+ article.id)
      });
    }
    else{
        console.log('removing like',new Date);
        article.removeLike(user, function (err) {
            if (err) return res.render('500')
            res.redirect('/articles/'+ article.id)
        });

    }

});

schema methods:

addLike: function (user, cb){

this.likes.push({
  user: user._id
})

this.save(cb);
},

removeLike: function (user, cb){
    var that = this;
    this.likes.forEach(function(like, index) { 
      if(like.user == user.id){
         var newLikesObj = that.likes.toObject(); 
         console.log("before splice:\n ",newLikesObj);
         newLikesObj.splice(index,1);
         console.log("after splice: \n",newLikesObj);
         that.likes = newLikesObj;
         that.save(cb)

      }
});

and from logs splice seems to be working ok

before splice:
  [ { user: 5247095b5696e45c2b000102,
    _id: 524defc87153550829000103,
    createdAt: Fri Oct 04 2013 01:29:28 GMT+0300 (Финляндия (лето)) },
  { user: 5247095b5696e45c2b000002,
    _id: 524df3c2a663050805000003,
    createdAt: Fri Oct 04 2013 01:46:26 GMT+0300 (Финляндия (лето)) } ]
after splice:
 [ { user: 5247095b5696e45c2b000102,
    _id: 524defc87153550829000103,
    createdAt: Fri Oct 04 2013 01:29:28 GMT+0300 (Финляндия (лето)) } ]

static method:

getArticleByWithLikesByUserId: function (id, cb) {
    this.find({ 'likes.user' : id })
      .populate('user', 'name email username')
      .populate('comments.user')
      .exec(cb)
  }

I've also tried this update method, still doesnt remove like even though numberAffected is showing 1

this.update({$pull : {'likes.user':user.id}}, function(err, numberAffected){
    if(!err){
      return console.log('like removed');
    } else {
      return console.log(err);
    }
 });
like image 958
Leg0 Avatar asked Feb 03 '26 17:02

Leg0


1 Answers

I can't say what's going wrong with your example, other than that you're going about it the wrong way. MongoDB provides an an easier, built in way to remove items from an array either by specifying the exactly, or via a query:

Behold the $pull operator.

In mongoose one way to do this would be:

Article.findByIdAndUpdate(this._id, {
  $pull: {
    likes: {user: user._id}
  }
}, cb);
like image 98
numbers1311407 Avatar answered Feb 06 '26 06:02

numbers1311407



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!