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


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

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

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

Ответы:


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 для получения дополнительной информации.


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.


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

18

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

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

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

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

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

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

  User.remove({...}, callback);


12

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

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

    });

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


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

9

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

MyModel.remove({search: criteria}, function() {
    // removed.
});

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"
        })
    }

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

Model.removeустарела
Maxwell sc


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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.