¿Cómo elimino documentos usando Node.js Mongoose?


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

Lo anterior no parece funcionar. Los registros aún están allí.

Alguien puede arreglar?

Respuestas:


489

Si no tiene ganas de iterar, intente FBFriendModel.find({ id:333 }).remove( callback );oFBFriendModel.find({ id:333 }).remove().exec();

mongoose.model.finddevuelve una consulta , que tiene una removefunción .

Actualización para Mongoose v5.5.3: remove()ahora está en desuso. Uso deleteOne(), deleteMany()ofindOneAndDelete() instead.


3
¿Esto ejecuta middleware pre / post-remove? (algunos métodos modelo omiten el middleware de documentos y no estoy seguro de si este es uno de ellos, los documentos no están claros)
hunterloftis 05 de

12
Supongo que @hunterloftis ya lo ha descubierto, pero para cualquiera que lea la respuesta es no, esto no ejecutará pre / post middleware en documentos individuales.
números1311407

Esto parece que muchas de las otras respuestas mencionan, .exec()sin embargo, esto no lo hace en absoluto. Es .exec()necesario, ¿hay efectos secundarios al usarlo o no?
DanH

Los documentos son claros (tal vez se hayan actualizado) de que esto pasa por alto el middleware (consulte la parte inferior de mongoosejs.com/docs/middleware.html) , así que tenga cuidado, usar este método puede causar problemas serios y difíciles de rastrear.
Jed Watson

1
¡gran respuesta! ¿Cuáles son los argumentos de la devolución de llamada?
k88074

299

ACTUALIZACIÓN: versión de mangosta (5.5.3)

remove () está en desuso y puede usar deleteOne (), deleteMany () o bulkWrite () en su lugar.

A partir de entonces "mongoose": ">=2.7.1", puede eliminar el documento directamente con el .remove()método en lugar de encontrar el documento y luego eliminarlo, lo que me parece más eficiente y fácil de mantener.

Ver ejemplo:

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

ACTUALIZAR:

A partir de la mangosta 3.8.1, hay varios métodos que le permiten eliminar directamente un documento, por ejemplo:

  • remove
  • findByIdAndRemove
  • findOneAndRemove

Consulte los documentos de la API de mangosta para obtener más información.


13
Como se señaló en otros comentarios a otras respuestas, esto pasa por alto el middleware que se define en el esquema y puede ser realmente peligroso. Así que solo úsalo si entiendes el impacto que tendrá. Para obtener más información, visite mongoosejs.com/docs/middleware.html
Jed Watson

2
Solo para que conste, hasta ahora siempre los he usado sin ningún efecto secundario, claro, no tuve que usar ningún middleware en mis proyectos :)
diosney

8
remove(query)potencialmente podría vaciar toda su colección si pasa accidentalmente query = {}. Por esa razón, prefiero findOneAndRemove(query)si solo estoy eliminando un documento.
joeytwiddle

1
También tenga en cuenta que esto no devuelve una consulta, por lo que tampoco es una promesa. No puedes hacerModel.remove({ _id: 'whatever' }).exec().then(...)
David

48

docses una serie de documentos entonces no tiene un mongooseModel.remove()método.

Puede iterar y eliminar cada documento en la matriz por separado.

O - ya que parece que se están encontrando los documentos de un (probablemente) Identificación única - utilizar findOneen lugar de find.


55
Como esta respuesta supone una versión bastante antigua de mangosta, realmente no me opondría a que alguien cambie la respuesta aceptada.
mtkopone

Esta es en realidad una de las mejores formas de hacerlo porque invoca correctamente el middleware definido en el esquema; consulte mongoosejs.com/docs/middleware.html . Solo debe usar los otros métodos si NO está usando middleware en su aplicación, y luego con precaución.
Jed Watson

41

Esto para mí es lo mejor a partir de la versión 3.8.1:

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

Y solo requiere una llamada de DB. Use esto dado que no realiza ninguna removeacción previa a la búsqueda y eliminación.


1
Siempre que no necesite realizar pre 'remove'acciones, funciona bien.
Daniel Kmak

32

Simplemente haz

FBFriendModel.remove().exec();

1
Simple y efectivo.
Rich Apodaca

1
¿Esto devuelve una promesa? Si es así, ¿qué objeto se define cuando se resuelve la promesa?
Kenny Worden

@KennyWorden un enfoque efectivo para encontrar la respuesta -> mongoosejs.com/docs/api.html luego busque lo que desea pero anteponga '#' a la búsqueda en la página con su navegador, como buscar en '#save' y usted Veré que devuelve una promesa.
Jason Sebring

3
Esta es una especie de respuesta peligrosa sin poner la condición de la
operación

29

mongoose.model.find()devuelve un objeto de consulta que también tiene una remove()función.

También puede usar mongoose.model.findOne(), si desea eliminar solo un documento único.

De lo contrario, también puede seguir el enfoque tradicional donde primero recupera el documento y luego lo elimina.

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

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

Las siguientes son las formas en las modelque puede realizar cualquiera de los siguientes procedimientos para eliminar documentos:

yourModelObj.findOneAndRemove(conditions, options, callback)

yourModelObj.findByIdAndRemove(id, options, callback)

yourModelObj.remove(conditions, callback);

var query = Comment.remove({ _id: id });
query.exec();

22

remove()ha quedado en desuso Uso deleteOne(), deleteMany()o bulkWrite().

El código que uso

TeleBot.deleteMany({chatID: chatID}, function (err, _) {
                if (err) {
                    return console.log(err);
                }
            });

1
Esta respuesta honestamente necesita más votos a favor. Se coloca injustamente en el fondo del barril (porque no ha recibido media década de votos anticuados), pero es la única respuesta que resuelve el problema de:(node:9132) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
Steven Ventimiglia

18

Para generalizar puedes usar:

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

Otra forma de lograr esto es:

SomeModel.collection.remove( function (err) {
  if (err) throw err;
  // collection is now empty but not deleted
});

18

¡Tenga cuidado con findOne y elimínelo!

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

El código anterior elimina TODOS los usuarios llamados 'Alice' en lugar de solo el primero .

Por cierto, prefiero eliminar documentos como este:

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

O proporcione una devolución de llamada y omita el exec ()

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


12

Si está buscando eliminar solo un objeto, puede usar

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

    });

En este ejemplo, Mongoose se eliminará en función de la combinación de req.params.id.


Bienvenido a Stackoverflow. Su respuesta es un duplicado de múltiples respuestas en este hilo. Además, siempre debe verificar si hay errores en sus devoluciones de llamada.
VtoCorleone

9

.remove()funciona como .find():

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

9

Prefiero la notación de promesa, donde la necesitas

Model.findOneAndRemove({_id:id})
    .then( doc => .... )

7

Para eliminar documentos, prefiero usar Model.remove(conditions, [callback])

Consulte la documentación de la API para eliminar: -

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

Para este caso, el código será: -

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

Si desea eliminar documentos sin esperar una respuesta de MongoDB, no pase una devolución de llamada, entonces debe llamar a exec en la Consulta devuelta

var removeQuery = FBFriendModel.remove({id : 333 });
removeQuery.exec();

6

Puede usar la consulta directamente dentro de la función remove, por lo que:

FBFriendModel.remove({ id: 333}, function(err){});

6

Siempre puede usar la función incorporada 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

Actualización: .remove()se deprecia pero todavía funciona para versiones anteriores

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

Model.remove está en desuso
Maxwell sc

2

usando el método remove () puedes eliminarlo.

getLogout(data){
        return this.sessionModel
        .remove({session_id: data.sid})
        .exec()
        .then(data =>{
            return "signup successfully"
        })
    }

Model.remove está en desuso
Maxwell sc

1
Maxwell sc, haga una solicitud de edición y corríjala. Sé que eres nuevo en SO, pero es mucho más útil arreglarlo que comentar que está depreciado. Tal vez podría sugerir una edición la próxima vez, o hacer una edición usted mismo, y tomar un poco de propiedad de la situación ...
Joshua Michael Waggoner

1

Esto funcionó para mí, solo prueba esto:

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.removeestá en desuso
Maxwell sc

1

Según la respuesta de Samyak Jain, uso Async Await

let isDelete = await MODEL_NAME.deleteMany({_id:'YOUR_ID', name:'YOUR_NAME'});

0

Realmente me gusta este patrón en aplicaciones Express / Mongoose asíncronas / en espera :

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.