¿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?

TIMEX
fuente

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.

Yusuf X
fuente
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.

diosney
fuente
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.

mtkopone
fuente
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.

José Pinto
fuente
1
Siempre que no necesite realizar pre 'remove'acciones, funciona bien.
Daniel Kmak
32

Simplemente haz

FBFriendModel.remove().exec();
Sandro Munda
fuente
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();
Amol M Kulkarni
fuente
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);
                }
            });
Samyak Jain
fuente
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
});
alexandru.topliceanu
fuente
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);
Damphat
fuente
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.

bhavsac
fuente
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.
});
trusktr
fuente
9

Prefiero la notación de promesa, donde la necesitas

Model.findOneAndRemove({_id:id})
    .then( doc => .... )
Simon H
fuente
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();
satyam kumar
fuente
6

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

FBFriendModel.remove({ id: 333}, function(err){});
David Losert
fuente
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;
    });
Doron Segal
fuente
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 }`
    })
});
Joshua Michael Waggoner
fuente
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"
        })
    }
KARTHIKEYAN.A
fuente
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
        })
      });
MEAbid
fuente
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'});
Renote Gotecha
fuente
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)
}))
corysimmons
fuente
-2
db.collection.remove(<query>,
 {
  justOne: <boolean>,
  writeConcern: <document>
})
Rushabh.js
fuente
@ MR: ¿Cómo puede ser solo enlace cuando no hay un enlace en la respuesta? También puedes ver: mensajes de baja calidad y de código sólo responde
BDL
Sry hace clic mal. Pero aún así es de baja calidad.
MR