166

I'm using the Mongoose Library for accessing MongoDB with node.js

Is there a way to remove a key from a document? i.e. not just set the value to null, but remove it?

User.findOne({}, function(err, user){
  //correctly sets the key to null... but it's still present in the document
  user.key_to_delete = null;

  // doesn't seem to have any effect
  delete user.key_to_delete;

  user.save();
});
2
  • 1
    I thought I had found it, but after some tests: probably not. This has some good discussion on the topic though. groups.google.com/group/mongoose-orm/browse_thread/thread/… Commented Aug 15, 2011 at 15:28
  • LOL nevermind, I guess this was your post! Commented Aug 15, 2011 at 15:31

11 Answers 11

251

In early versions, you would have needed to drop down the node-mongodb-native driver. Each model has a collection object that contains all the methods that node-mongodb-native offers. So you can do the action in question by this:

User.collection.update({_id: user._id}, {$unset: {field: 1 }});

Since version 2.0 you can do:

User.update({_id: user._id}, {$unset: {field: 1 }}, callback);

And since version 2.4, if you have an instance of a model already you can do:

doc.field = undefined;
doc.save(callback);
Sign up to request clarification or add additional context in comments.

12 Comments

Either use User.update({ _id: id }, { $unset: { field: 1 }}, callback) or if you have a document instance, set the path to undefined and then save it: doc.field = undefined; doc.save()
Just a note that if you're trying to remove an old property that's no longer defined in your schema you need to do doc.set('field', undefined)
what about deleting doc.field.foo ?
@evilcelery doc.set('field', undefined) might not be enough since strict mode (default) does not allow to set fields which are not in the schema anymore. doc.set('field', undefined, { strict: false }) worked fine.
none of the other comments work. it should be something like this: User.updateOne({ _id: user._id }, { $unset: { field: 1 }}, { strict: false }).
|
74

You'll want to do this:

User.findOne({}, function(err, user){
  user.key_to_delete = undefined;
  user.save();
});

2 Comments

That will just set it to null - not what the OP is asking for.
As of version 2.4.0 setting a document key to undefined will pass the $unset to mongodb aaronheckmann.posterous.com/mongoose-240
57

I use mongoose and using any of the above functions did me the requirement. The function compiles error free but the field would still remain.

user.set('key_to_delete', undefined, {strict: false} );

did the trick for me.

4 Comments

Upvoting this useful answer, too bad @alexander-link didn't make it an answer back in 2015 (stackoverflow.com/questions/4486926/…)
Thank you for your answer, for me, the other solutions did not work for objects nested in arrays!
@BenSower This was my case, too. Only this solution worked well because I had to delete a field with array after finding a specific document's id
Note that the string is a path to the key. So, if the object you want to delete is nested, you must path to it. This answer solved my problem!
13

At mongo syntax to delete some key you need do following:

{ $unset : { field : 1} }

Seems at Mongoose the same.

Edit

Check this example.

2 Comments

Can you clarify this answer and give a code example that relates to the example code above?
sorry but i am not expereinced at mongoose. Above syntax it's mongo syntax, so i suppose that driver for any language support this. I found some example, check it in my answer.
3

if you want to remove a key from collection try this method.

 db.getCollection('myDatabaseTestCollectionName').update({"FieldToDelete": {$exists: true}}, {$unset:{"FieldToDelete":1}}, false, true);

1 Comment

I don't believe the question was about removing the field from all documents in the collection, which is what this does
2

Try:

User.findOne({}, function(err, user){
  // user.key_to_delete = null; X
  `user.key_to_delete = undefined;`

  delete user.key_to_delete;

  user.save();
});

Comments

1

Could this be a side problem like using

function (user)

instead of

function(err, user)

for the find's callback ? Just trying to help with this as I already had the case.

Comments

1

Mongoose document is NOT a plain javascript object and that's why you can't use delete operator.(Or unset from 'lodash' library).

Your options are to set doc.path = null || undefined or to use Document.toObject() method to turn mongoose doc to plain object and from there use it as usual. Read more in mongoose api-ref: http://mongoosejs.com/docs/api.html#document_Document-toObject

Example would look something like this:

User.findById(id, function(err, user) {
    if (err) return next(err);
    let userObject = user.toObject();
    // userObject is plain object
});

Comments

1

the problem with all of these answers is that they work for one field. for example let's say i want delete all fields from my Document if they were an empty string "". First you should check if field is empty string put it to $unset :

function unsetEmptyFields(updateData) {
  const $unset = {};
  Object.keys(updatedData).forEach((key) => {
    if (!updatedData[key]) {
      $unset[key] = 1;
      delete updatedData[key];
    }
  });
  updatedData.$unset = $unset;

  if (isEmpty(updatedData.$unset)) { delete updatedData.$unset; }

  return updatedData;
}

function updateUserModel(data){
const updatedData = UnsetEmptyFiled(data);

    const Id = "";
    User.findOneAndUpdate(
      { _id: Id },
      updatedData, { new: true },
    );
}

Comments

0

await yourModel.findByIdAndUpdate( _id, { $set: updateFields, $unset: { fieldToDelete: 1 } }, { new: true } );

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
-6

you can use delete user._doc.key

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.