Mongoose isn't removing embedded documents

655 views
Skip to first unread message

Matt McManus

unread,
Mar 15, 2011, 4:34:10 PM3/15/11
to mongoo...@googlegroups.com
I've also posted this on stackoverflow: http://stackoverflow.com/questions/5316709/mongoose-wont-remove-embedded-documents

I'm running into an issue where mongoose won't remove embedded docs when I'm editing an existing document. I've got a schema of Server that can have any number of embedded docs called services. I'm running into a problem though where, even though I've successfully removed the individual service from the server object, when I tell it to save it just doesn't remove it. The save function is working because it's saving any content changes I've made and is also pushing new embedded docs in, it's just not removing existing ones.

Here is a simplified example:

app.put('/server/:id', function(req, res, next){
  app.Server.findOne({_id: req.params.id}, function(err, server) {
    server.updated = new Date();
    ...

    for (var num = _.size(req.body.server.services) - 1; num >= 0; num--){
      // Is this a new service or an existing one
      if (server.services[num]) {
        // Is it marked for deletion? If so, delete it
        if (req.body.server.services[num].delete == "true") {
          server.services[num].remove()
        } else { // else, update it
          server.services[num].type = req.body.server.services[num].type
          ...
        }
      } else {
        // It's new, add it
        delete req.body.server.services[num]["delete"]
        server.services.push(req.body.server.services[num]);
      }
    }

    server.save(function(err){
      if (!err) {
        req.flash('success', 'Server updated')
      } else {
        req.flash('error', 'Err, Something broke when we tried to save your server. Sorry!')
        console.log(err)
      }
      res.redirect('/')
    });
  })
});

So the remove() is actually removing that service. If I do a server.toObject() before the save, it's not there.

Any ideas why it wouldn't be removing it when it saves?

Carlos Eduardo de Paula

unread,
Mar 19, 2011, 12:54:52 PM3/19/11
to mongoo...@googlegroups.com
Same problem here. Similar code.

Running Turtle

unread,
Mar 19, 2011, 4:54:30 PM3/19/11
to Mongoose Node.JS ORM
Not sure if it is the same problem, but I'm also having trouble
removing stuff :

When I execute the following:

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

mongoose.connect('mongdb://localhost/test');

var DocSchema = new Schema({
title: { type: String },
tags: [String]
});

mongoose.model('Documents', DocSchema);

var Documents = mongoose.model('Documents');

var newDoc = new Documents({
title: 'Title',
tags: ['tag1', 'tag2']
});

newDoc.save(function(err) {
if (err) { throw err; } else {
console.log('doc saved');
}
})

newDoc is correctly saved.
But when I do :

Documents.findOne({title: 'Title'}, function(err, document) {
document.tags[0].remove;
document.save(function(err) {
if (err) { throw err; } else {
console.log('tag removed');
}
})
})

I have the message 'tag removed', but when I grab the document in the
console, it hasn't changed ...

On Mar 15, 9:34 pm, Matt McManus <mattmcma...@gmail.com> wrote:
> I've also posted this on stackoverflow:http://stackoverflow.com/questions/5316709/mongoose-wont-remove-embed...

Carlos Eduardo de Paula

unread,
Mar 19, 2011, 5:49:02 PM3/19/11
to mongoo...@googlegroups.com
That's exactly the sane problem. I posted a workaround on
StackExchange. The link is in the first message.

Carlos

Sent from my iPhone

Matt McManus

unread,
Mar 21, 2011, 5:26:44 PM3/21/11
to mongoo...@googlegroups.com, Carlos Eduardo de Paula
Thank you Carlos! You're workaround worked. Splicing out the specific embedded doc instead of removing it works. 

Anyone have any idea why it would do this? Is the dev team aware? Should I make a ticket?

Carlos Eduardo de Paula

unread,
Mar 21, 2011, 5:35:16 PM3/21/11
to mongoo...@googlegroups.com
No problems, I think the devs should be aware of this problem.

In my point of view, there should exist something like:

docs.users[id].remove();

or

delete docs.users[id];

Would you open an issue?

Thanks!


On Mon, Mar 21, 2011 at 6:26 PM, Matt McManus <mattm...@gmail.com> wrote:
Thank you Carlos! You're workaround worked. Splicing out the specific embedded doc instead of removing it works. 

Anyone have any idea why it would do this? Is the dev team aware? Should I make a ticket?



--
______________________________
Carlos Eduardo de Paula
carl...@gmail.com
http://blog.carlosedp.com
http://twitter.com/carlosedp
______________________________

Jehu

unread,
Apr 7, 2011, 8:55:27 AM4/7/11
to Mongoose Node.JS ORM
Hi, it works in my example:

doc.embeddedItem.forEach(function(item) {
doc.embeddedItem.id(item.doc._id).remove();
});
doc.save(function(err){
...
});

See also: http://mongoosejs.com/docs/embedded-documents.html

(mongo db version v1.6.5, mongoose 1.1.24)


On 21 Mrz., 23:35, Carlos Eduardo de Paula <carlos...@gmail.com>
wrote:
> No problems, I think the devs should be aware of this problem.
>
> In my point of view, there should exist something like:
>
> docs.users[id].remove();
>
> or
>
> delete docs.users[id];
>
> Would you open an issue?
>
> Thanks!
>
> On Mon, Mar 21, 2011 at 6:26 PM, Matt McManus <mattmcma...@gmail.com> wrote:
> > Thank you Carlos! You're workaround worked. Splicing out the specific
> > embedded doc instead of removing it works.
>
> > Anyone have any idea why it would do this? Is the dev team aware? Should I
> > make a ticket?
>
> --
> ______________________________
> *Carlos Eduardo de Paula*
> carlos...@gmail.comhttp://blog.carlosedp.comhttp://twitter.com/carlosedp
> ______________________________

Carlos Eduardo de Paula

unread,
Apr 7, 2011, 9:20:37 AM4/7/11
to mongoo...@googlegroups.com
Have you checked that after removing the embedded doc and saving the document, the embedded doc had really been removed? Because it does not throw any error but the parent is not reflecting the removal.

Carlos

Jehu

unread,
Apr 8, 2011, 8:48:58 AM4/8/11
to Mongoose Node.JS ORM
Oh, sorry. I thought I had tested that explicitly. But today it does
not for me.

Jehu

unread,
May 25, 2011, 4:00:53 AM5/25/11
to Mongoose Node.JS ORM
Ok. Now i've got it working with a workaround.
Unfortunately, a lot of code for such a simple task...

app.del('/tags/:id.json', function(req, res) {
Contact.findById(req.body.contact_id, function(err, doc) {
if(!err) {
var index = 0;
doc.tags.forEach(function(item) {
if(item._id == req.params.id) {
var newTagsObj = doc.tags.toObject();
newTagsObj.splice(index,1)
Contact.update(
{ _id: req.body.contact_id },
{ 'tags': newTagsObj },
function(err) {
if(!err) {
res.send({success: true});
}
}
);
return false;
}
index += 1;
});
}
})
});
Reply all
Reply to author
Forward
0 new messages