Как удалить документы с помощью Node.js Mongoose?

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

Выше, кажется, не работает. Записи все еще там.

Может кто-нибудь исправить?

TIMEX
источник

Ответы:

489

Если вам не хочется повторяться, попробуйте FBFriendModel.find({ id:333 }).remove( callback );илиFBFriendModel.find({ id:333 }).remove().exec();

mongoose.model.findвозвращает запрос , который имеет removeфункцию .

Обновление Mongoose v5.5.3 - remove()устарело. Использование deleteOne(), deleteMany()илиfindOneAndDelete() instead.

Юсуф Икс
источник
3
Работает ли промежуточное ПО до / после удаления? (некоторые модельные методы обходят промежуточное программное обеспечение документа, и я не уверен, является ли это одним из них, документы неясны)
hunterloftis
12
Я предполагаю, что @hunterloftis уже понял это, но для всех, кто прочитает ответ, нет, это не будет запускать промежуточное программное обеспечение до / после на отдельных документах.
1311407
Кажется, что во многих других ответах упоминается, .exec()но это совсем не так. Является ли это .exec()необходимо, есть ли побочные эффекты использовать его или нет?
DanH
Документы ясны (возможно, они были обновлены), что это обходит промежуточное ПО - см. Нижнюю часть mongoosejs.com/docs/middleware.html - поэтому будьте осторожны, использование этого метода может вызвать серьезные, трудно выявляемые проблемы.
Джед Уотсон
1
отличный ответ! Каковы аргументы обратного вызова?
k88074
299

ОБНОВЛЕНИЕ: версия Mongoose (5.5.3)

Удаление () устарело, и вы можете использовать вместо него deleteOne (), deleteMany () или bulkWrite ().

Как "mongoose": ">=2.7.1"вы можете удалить документ непосредственно с.remove() метода, а не найти документ, а затем удалить его, что мне кажется более эффективным и простым в обслуживании.

Смотрите пример:

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

ОБНОВИТЬ:

Что касается мангуста 3.8.1, есть несколько методов, которые позволяют вам напрямую удалить документ, скажем:

  • remove
  • findByIdAndRemove
  • findOneAndRemove

Обратитесь к документации mongoose API для получения дополнительной информации.

diosney
источник
13
Как отмечалось в других комментариях к другим ответам, это обходит промежуточное программное обеспечение, определенное в схеме, и может быть действительно опасным. Так что используйте его, только если вы понимаете, какое влияние это окажет. Для получения дополнительной информации см. Mongoosejs.com/docs/middleware.html
Джед Уотсон
2
Для справки, до сих пор я всегда использовал их без каких-либо побочных эффектов, конечно, мне не приходилось использовать какое-либо промежуточное ПО в моих проектах :)
diosney
8
remove(query)потенциально может очистить всю вашу коллекцию, если вы случайно пропустите query = {}. По этой причине я предпочитаю findOneAndRemove(query)удалять только один документ.
Joeytwiddle
1
Также обратите внимание, что это не возвращает запрос, так что ни обещание. Вы не можете сделатьModel.remove({ _id: 'whatever' }).exec().then(...)
Дэвид
48

docsэто массив документов. так что у него нетmongooseModel.remove() метода.

Вы можете перебирать и удалять каждый документ в массиве отдельно.

Или - поскольку похоже, что вы находите документы по (возможно) уникальному идентификатору - используйте findOneвместо find.

mtkopone
источник
5
Поскольку этот ответ предполагает довольно старую версию мангуста, я бы не стал возражать против того, чтобы кто-то изменил принятый ответ.
mtkopone
На самом деле это один из лучших способов сделать это, потому что он правильно вызывает промежуточное программное обеспечение, определенное в схеме - см. Mongoosejs.com/docs/middleware.html . Вы должны использовать другие методы, только если вы НЕ используете промежуточное программное обеспечение в своем приложении, а затем с осторожностью.
Джед Уотсон
41

Это для меня лучшее из версии 3.8.1:

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

И это требует только одного вызова БД. Используйте это, если вы не выполняете никаких removeдействий, связанных с поиском и удалением.

Хосе Пинто
источник
1
Пока вам не нужно выполнять какие-либо pre 'remove'действия, он работает нормально.
Даниэль Кмак
32

Просто делай

FBFriendModel.remove().exec();
Сандро Мунда
источник
1
Просто и эффективно.
Богатая Аподака
1
Это возвращает обещание? Если да, то какой объект определяется при выполнении Обещания?
Кенни Уорден
@KennyWorden эффективный подход к поиску ответа -> mongoosejs.com/docs/api.html, затем ищите то, что вы хотите, но добавьте «#» к поиску на странице в вашем браузере, например, поиск по «#save» и вы Посмотрим, вернется ли это обещание.
Джейсон Себринг
3
Это своего рода опасный ответ без постановки условия, указанного в удалении ...
blak3r
29

mongoose.model.find()возвращает объект запроса, который также имеет remove()функцию.

Вы также можете использовать mongoose.model.findOne(), если вы хотите удалить только один уникальный документ.

В противном случае вы также можете следовать традиционному подходу, когда сначала извлекаете документ, а затем удаляете.

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

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

Ниже приведены способы для modelобъекта, который вы можете сделать любым из следующих действий, чтобы удалить документ (ы):

yourModelObj.findOneAndRemove(conditions, options, callback)

yourModelObj.findByIdAndRemove(id, options, callback)

yourModelObj.remove(conditions, callback);

var query = Comment.remove({ _id: id });
query.exec();
Амол М Кулькарни
источник
22

remove()был объявлен устаревшим Используйте deleteOne(), deleteMany()или bulkWrite().

Код, который я использую

TeleBot.deleteMany({chatID: chatID}, function (err, _) {
                if (err) {
                    return console.log(err);
                }
            });
Самяк Джайн
источник
1
Этот ответ, честно говоря, нуждается в большем количестве голосов. Это несправедливо расположено в нижней части ствола (потому что он не получил пол-десятилетия устаревших голосов), но это единственный ответ, который решает проблему:(node:9132) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
Стивен Вентимилья
18

Для обобщения вы можете использовать:

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();
  });
});

Еще один способ добиться этого:

SomeModel.collection.remove( function (err) {
  if (err) throw err;
  // collection is now empty but not deleted
});
alexandru.topliceanu
источник
18

Будьте осторожны с findOne и удалите!

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

Приведенный выше код удаляет ВСЕХ пользователей с именем «Алиса» вместо первого .

Кстати, я предпочитаю удалять документы следующим образом:

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

Или предоставить обратный вызов и опустить exec ()

  User.remove({...}, callback);
damphat
источник
12

Если вы ищете только один объект для удаления, вы можете использовать

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

    });

В этом примере Mongoose удалит на основе соответствующего req.params.id.

bhavsac
источник
Добро пожаловать в Stackoverflow. Ваш ответ является дубликатом нескольких ответов в этой теме. Кроме того, вы всегда должны проверять наличие ошибок в ваших обратных вызовах.
VtoCorleone
9

.remove()работает как .find():

MyModel.remove({search: criteria}, function() {
    // removed.
});
trusktr
источник
9

Я предпочитаю обозначение обещания, где вам нужно, например,

Model.findOneAndRemove({_id:id})
    .then( doc => .... )
Саймон Х
источник
7

Для удаления документа я предпочитаю использовать Model.remove(conditions, [callback])

Пожалуйста, обратитесь к документации API для удаления: -

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

Для этого случая код будет:

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

Если вы хотите удалить документы, не ожидая ответа от MongoDB, не передавайте обратный вызов, тогда вам нужно вызвать exec для возвращенного запроса

var removeQuery = FBFriendModel.remove({id : 333 });
removeQuery.exec();
сатьям кумар
источник
6

Вы можете просто использовать запрос непосредственно в функции удаления, поэтому:

FBFriendModel.remove({ id: 333}, function(err){});
Дэвид Лозер
источник
6

Вы всегда можете использовать встроенную функцию Mongoose:

var id = req.params.friendId; //here you pass the id
    FBFriendModel
   .findByIdAndRemove(id)
   .exec()
   .then(function(doc) {
       return doc;
    }).catch(function(error) {
       throw error;
    });
Дорон Сигал
источник
5

Обновление: .remove()устарело, но это все еще работает для более старых версий

YourSchema.remove({
    foo: req.params.foo
}, function(err, _) {
    if (err) return res.send(err)
    res.json({
        message: `deleted ${ req.params.foo }`
    })
});
Джошуа Майкл Вагонер
источник
Model.remove устарела
Maxwell sc
2

используя метод remove () вы можете удалить.

getLogout(data){
        return this.sessionModel
        .remove({session_id: data.sid})
        .exec()
        .then(data =>{
            return "signup successfully"
        })
    }
KARTHIKEYAN.A
источник
Model.remove устарела
Maxwell sc
1
Maxwell sc, сделайте запрос на редактирование и исправьте. Я знаю, что вы новичок в SO, но гораздо полезнее исправить это, чем комментировать, что он устарел. Может быть, вы могли бы предложить редактировать в следующий раз, или сделать редактирование самостоятельно, и немного
Джошуа Майкл Вагонер,
1

Это сработало для меня, просто попробуйте это:

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
        })
      });
MEAbid
источник
Model.removeустарела
Maxwell sc
1

Согласно ответу Samyak Jain, я использую Async Await

let isDelete = await MODEL_NAME.deleteMany({_id:'YOUR_ID', name:'YOUR_NAME'});
Рениш Готеча
источник
0

Мне очень нравится этот шаблон в приложениях Express / Mongoose с поддержкой async / await :

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
источник