346
FBFriendModel.find({
    id: 333
}, function (err, docs) {
    docs.remove(); //Remove all the documents that match!
});

The above doesn't seem to work. The records are still there.

Can someone fix?

KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080

24 Answers24

551

If you don't feel like iterating, try

FBFriendModel.find({ id:333 }).remove( callback );

or

FBFriendModel.find({ id:333 }).remove().exec();

mongoose.model.find returns a Query, which has a remove function.

Update for Mongoose v5.5.3 - remove() is now deprecated. Use deleteOne(), deleteMany() or findOneAndDelete() instead.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Yusuf X
  • 14,513
  • 5
  • 35
  • 47
  • 4
    Does this run pre/post-remove middleware? (some model methods bypass document middleware and I'm not sure if this is one of them, the docs are unclear) – hunterloftis Aug 05 '13 at 02:25
  • 13
    I suppose @hunterloftis has figured this out already, but for anyone else reading the answer is no, this will not run pre/post middleware on individual docs. – numbers1311407 Nov 04 '13 at 22:26
  • This seems many of the other answers mention `.exec()` however this doesn't at all. Is `.exec()` needed, are there side effects to using it or not? – DanH Feb 02 '14 at 13:52
  • The docs are clear (maybe they've been updated) that this bypasses middleware - see the bottom of http://mongoosejs.com/docs/middleware.html - so be careful, using this method can cause serious, hard to track down issues. – Jed Watson May 13 '14 at 07:25
  • @DanH `.exec()` does an unsafe write and no callback is required for execution of removal. I'd stick with the callback, it's safer and you know what happened when something goes wrong, not to mention race condition problems. – Nijikokun Jan 13 '15 at 00:44
  • 1
    great answer! what are the arguments of the callback? – k88074 Jan 17 '15 at 19:47
  • If you click on "show code" you'll it calls the callback thusly: process.nextTick(callback.bind(null, err)); – Yusuf X Jan 19 '15 at 19:44
  • is `exec()` necessary? – CodyBugstein Jun 21 '15 at 15:35
  • this is nice, but what if I need to access the docs before/after removing them? FBFriendModel.find({ id:333 }).remove().exec(function(err, docs) { console.log(docs); // empty }); – Micha Schwab Jul 27 '15 at 20:24
  • Asked that question at http://stackoverflow.com/questions/31662783/mongoose-find-and-remove. – Micha Schwab Jul 27 '15 at 20:35
  • @numbers1311407, you are correct that these methods bypass middleware, but what would be the right way to remove AND call middleware? I am trying to remove referenced documents in the .pre('remove') – dcoffey3296 Nov 21 '17 at 03:55
  • remove().exec() -> deleteMany() – German Khokhlov Jun 01 '22 at 05:41
315

UPDATE: Mongoose version (5.5.3)

remove() is deprecated and you can use deleteOne(), deleteMany(), or bulkWrite() instead.

As of "mongoose": ">=2.7.1" you can remove the document directly with the .remove() method rather than finding the document and then removing it which seems to me more efficient and easy to maintain.

See example:

Model.remove({ _id: req.body.id }, function(err) {
    if (!err) {
            message.type = 'notification!';
    }
    else {
            message.type = 'error';
    }
});

UPDATE:

As of mongoose 3.8.1, there are several methods that lets you remove directly a document, say:

  • remove
  • findByIdAndRemove
  • findOneAndRemove

Refer to mongoose API docs for further information.

Community
  • 1
  • 1
Diosney
  • 10,520
  • 15
  • 66
  • 111
  • 13
    As noted in other comments to other answers, this bypasses middleware that is defined on the schema, and can be really dangerous. So only use it if you understand the impact that will have. For more info, see http://mongoosejs.com/docs/middleware.html – Jed Watson May 13 '14 at 07:28
  • 2
    Just for the record, until now I always have used them without any side effects, sure, I hadn't to use any middleware in my projects :) – Diosney May 14 '14 at 11:56
  • 8
    `remove(query)` could potentially empty *your entire collection* if you accidentally pass `query = {}`. For that reason I prefer `findOneAndRemove(query)` if I am only removing *one* document. – joeytwiddle Sep 14 '16 at 04:14
  • 1
    Also note that this is not returning a query, so neither a promise. You **can't** do `Model.remove({ _id: 'whatever' }).exec().then(...)` – David Sep 20 '16 at 15:01
54

docs is an array of documents. so it doesn't have a mongooseModel.remove() method.

You can iterate and remove each document in the array separately.

Or - since it looks like you are finding the documents by a (probably) unique id - use findOne instead of find.

shybovycha
  • 11,556
  • 6
  • 52
  • 82
mtkopone
  • 5,955
  • 2
  • 27
  • 30
  • 6
    Seeing as this answer assumes a rather old version of mongoose, I really wouldn't object to someone changing the accepted answer. – mtkopone May 12 '14 at 12:01
  • This is actually one of the best ways to do it because it correctly invokes middleware defined on the schema - see http://mongoosejs.com/docs/middleware.html. You should only use the other methods if you're NOT using middleware in your application, and then with caution. – Jed Watson May 13 '14 at 07:26
50

This for me is the best as of version 3.8.1:

MyModel.findOneAndRemove({field: 'newValue'}, function(err){...});

And it requires only one DB call. Use this given that you don't perform any remove actions pior to the search and removal.

José Pinto
  • 686
  • 6
  • 11
43

remove() has been deprecated. Use deleteOne(), deleteMany() or bulkWrite().

The code I use

TeleBot.deleteMany({chatID: chatID}, function (err, _) {
                if (err) {
                    return console.log(err);
                }
            });
Samyak Jain
  • 571
  • 4
  • 4
  • 5
    This answer honestly needs more upvotes. It's unfairly placed at the bottom of the barrel (because it hasn't been getting a half-decade of antiquated votes), but is the only answer that solves the issue of: `(node:9132) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.` – Steven Ventimiglia Feb 28 '19 at 07:47
31

Simply do

FBFriendModel.remove().exec();
nbro
  • 15,395
  • 32
  • 113
  • 196
Sandro Munda
  • 39,921
  • 24
  • 98
  • 123
  • 1
    Does this return a Promise? If so, what object is defined when the Promise is resolved? – Kenny Worden Feb 10 '16 at 15:45
  • @KennyWorden an effective approach to find the answer -> http://mongoosejs.com/docs/api.html then search for what you want but prepend '#' to the in-page search with your browser such as search on '#save' and you'll see it returns a promise. – King Friday Jun 06 '16 at 00:02
  • 4
    This is kind of a dangerous answer without putting the condition the op specified in the remove... – blak3r Aug 08 '16 at 01:48
30

mongoose.model.find() returns a Query Object which also has a remove() function.

You can use mongoose.model.findOne() as well, if you want to remove only one unique document.

Else you can follow traditional approach as well where you first retrieving the document and then remove.

yourModelObj.findById(id, function (err, doc) {
    if (err) {
        // handle error
    }

    doc.remove(callback); //Removes the document
})

Following are the ways on model object you can do any of the following to remove document(s):

yourModelObj.findOneAndRemove(conditions, options, callback)

yourModelObj.findByIdAndRemove(id, options, callback)

yourModelObj.remove(conditions, callback);

var query = Comment.remove({ _id: id });
query.exec();
nbro
  • 15,395
  • 32
  • 113
  • 196
Amol M Kulkarni
  • 21,143
  • 34
  • 120
  • 164
21

To generalize you can use:

SomeModel.find( $where, function(err,docs){
  if (err) return console.log(err);
  if (!docs || !Array.isArray(docs) || docs.length === 0) 
    return console.log('no docs found');
  docs.forEach( function (doc) {
    doc.remove();
  });
});

Another way to achieve this is:

SomeModel.collection.remove( function (err) {
  if (err) throw err;
  // collection is now empty but not deleted
});
alexandru.topliceanu
  • 2,364
  • 2
  • 27
  • 38
19

Be careful with findOne and remove!

  User.findOne({name: 'Alice'}).remove().exec();

The code above removes ALL users named 'Alice' instead of the first one only.

By the way, I prefer to remove documents like this:

  User.remove({...}).exec();

Or provide a callback and omit the exec()

  User.remove({...}, callback);
Talha Awan
  • 4,573
  • 4
  • 25
  • 40
damphat
  • 18,246
  • 8
  • 45
  • 59
15
model.remove({title:'danish'}, function(err){
    if(err) throw err;
});

Ref: http://mongoosejs.com/docs/api.html#model_Model.remove

Danish
  • 503
  • 3
  • 14
14

If you are looking for only one object to be removed, you can use

Person.findOne({_id: req.params.id}, function (error, person){
        console.log("This object will get deleted " + person);
        person.remove();

    });

In this example, Mongoose will delete based on matching req.params.id.

bhavsac
  • 141
  • 1
  • 2
  • Welcome to Stackoverflow. Your answer is a duplicate of multiple answers in this thread. Also, you should always check for error in your callbacks. – VtoCorleone Apr 02 '16 at 18:36
9

.remove() works like .find():

MyModel.remove({search: criteria}, function() {
    // removed.
});
trusktr
  • 44,284
  • 53
  • 191
  • 263
9

I prefer the promise notation, where you need e.g.

Model.findOneAndRemove({_id:id})
    .then( doc => .... )
Simon H
  • 20,332
  • 14
  • 71
  • 128
7

For removing document, I prefer using Model.remove(conditions, [callback])

Please refer API documentation for remove :-

http://mongoosejs.com/docs/api.html#model_Model.remove

For this case, code will be:-

FBFriendModel.remove({ id : 333 }, function(err, callback){
console.log(‘Do Stuff’);
})

If you want to remove documents without waiting for a response from MongoDB, do not pass a callback, then you need to call exec on the returned Query

var removeQuery = FBFriendModel.remove({id : 333 });
removeQuery.exec();
satyam kumar
  • 1,467
  • 13
  • 7
6

You can just use the query directly within the remove function, so:

FBFriendModel.remove({ id: 333}, function(err){});
David Losert
  • 4,652
  • 1
  • 25
  • 31
6

You can always use Mongoose built-in function:

var id = req.params.friendId; //here you pass the id
    FBFriendModel
   .findByIdAndRemove(id)
   .exec()
   .then(function(doc) {
       return doc;
    }).catch(function(error) {
       throw error;
    });
kkochanski
  • 2,178
  • 23
  • 28
Doron Segal
  • 2,242
  • 23
  • 22
5

Update: .remove() is depreciated but this still works for older versions

YourSchema.remove({
    foo: req.params.foo
}, function(err, _) {
    if (err) return res.send(err)
    res.json({
        message: `deleted ${ req.params.foo }`
    })
});
4

I really like this pattern in async/await capable Express/Mongoose apps:

app.delete('/:idToDelete', asyncHandler(async (req, res) => {
  const deletedItem = await YourModel
    .findByIdAndDelete(req.params.idToDelete) // This method is the nice method for deleting
    .catch(err => res.status(400).send(err.message))

  res.status(200).send(deletedItem)
}))
corysimmons
  • 7,296
  • 4
  • 57
  • 65
2

using remove() method you can able to remove.

getLogout(data){
        return this.sessionModel
        .remove({session_id: data.sid})
        .exec()
        .then(data =>{
            return "signup successfully"
        })
    }
John Culviner
  • 22,235
  • 6
  • 55
  • 51
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
  • Model.remove is deprecated – Maxwell s.c Mar 29 '19 at 12:24
  • 1
    Maxwell s.c, make an edit request then, and correct. I know you're new to SO, but it's way more helpful to fix it than to comment that it's depreciated. Maybe you could suggest an edit next time, or make an edit yourself, and take a little ownership of the situation... – Joshua Michael Calafell Mar 29 '19 at 16:10
2

As per Samyak Jain's Answer, i use Async Await

let isDelete = await MODEL_NAME.deleteMany({_id:'YOUR_ID', name:'YOUR_NAME'});
Renish Gotecha
  • 2,232
  • 22
  • 21
1

This worked for me, just try this:

const id = req.params.id;
      YourSchema
      .remove({_id: id})
      .exec()
      .then(result => {
        res.status(200).json({
          message: 'deleted',
          request: {
            type: 'POST',
            url: 'http://localhost:3000/yourroutes/'
          }
        })
      })
      .catch(err => {
        res.status(500).json({
          error: err
        })
      });
Daniel
  • 3,541
  • 3
  • 33
  • 46
MEAbid
  • 560
  • 7
  • 11
1

To delete a single document you can use deleteOne() or remove()with single:true and deleteMany() or remove() to delete multiple documents :-

  1. Using deleteOne()
    syntax
    Model.deleteOne({conditions},function(err){});

    Example
     Model.deleteOne({title:"hi"},function(err){
        if(err)
        {
            res.send(err);
        }
        else{
            res.send("deleted");
        }
    });

2.Using remove()

    syntax
    Model.remove({conditions},{single:true},function(err){});

    Example
     Model.remove({title:"hi"},{single:true},function(err){
        if(err)
        {
            res.send(err);
        }
        else{
            res.send("deleted");
        }
    });

3.using deleteMany()

syntax
Model.deleteMany({conditions},function(err){});

    Example
     Model.deleteMany({title:"hi"},function(err){
        if(err)
        {
            res.send(err);
        }
        else{
            res.send("deleted");
        }
    });
  1. Using remove()
 syntax
    Model.remove({conditions},function(err){});

    Example
     Model.remove({title:"hi"},function(err){
        if(err)
        {
            res.send(err);
        }
        else{
            res.send("deleted");
        }
    });
1

if you know _id of the document you can use findByIdAndDelete(id) and this is is a shorthand for findOneAndDelete({ _id: id }).

import Question from '../models/Question';

const deleteQuestion = (questionId: string) => {
    try {
        Question.findByIdAndDelete(questionId);
    } catch (e) {
        console.error(e);
    }
};

here questionId is documentId (_id)

Supun Sandaruwan
  • 1,814
  • 19
  • 19
-2
db.collection.remove(<query>,
 {
  justOne: <boolean>,
  writeConcern: <document>
})
Rushabh.js
  • 11
  • 2
  • @M.R.: How can it be link-only when there is no link in the answer?? Also check: [Low quality posts and code only answers](https://meta.stackoverflow.com/questions/345719/low-quality-posts-and-code-only-answers) – BDL Jun 11 '19 at 08:21
  • Sry misclick. But still is a low quality. – Masoud Rahimi Jun 11 '19 at 09:03