Comment supprimer des documents à l'aide de Node.js Mongoose?


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

Ce qui précède ne semble pas fonctionner. Les enregistrements sont toujours là.

Quelqu'un peut-il réparer?

Réponses:


489

Si vous n'avez pas envie d'itérer, essayez FBFriendModel.find({ id:333 }).remove( callback );ouFBFriendModel.find({ id:333 }).remove().exec();

mongoose.model.findrenvoie une requête , qui a une removefonction .

La mise à jour pour Mongoose v5.5.3 - remove()est désormais obsolète. Utiliser deleteOne(), deleteMany()oufindOneAndDelete() instead.


3
Est-ce que cela exécute le middleware avant / après la suppression? (certaines méthodes de modèle contournent le middleware de document et je ne sais pas si c'est l'un d'entre eux, les documents ne sont pas clairs)
hunterloftis

12
Je suppose que @hunterloftis l'a déjà compris, mais pour quiconque lisant la réponse est non, cela ne fonctionnera pas avant / après le middleware sur les documents individuels.
numéros1311407

Cela semble que beaucoup d'autres réponses mentionnent, .exec()mais cela ne le fait pas du tout. Est-il .exec()nécessaire, y a-t-il des effets secondaires à l'utiliser ou non?
DanH

Les documents sont clairs (peut-être ont-ils été mis à jour) que ce contournement du middleware - voir le bas de mongoosejs.com/docs/middleware.html - alors soyez prudent, l'utilisation de cette méthode peut provoquer des problèmes graves et difficiles à localiser.
Jed Watson

1
très bonne réponse! quels sont les arguments du rappel?
k88074

299

MISE À JOUR: version Mongoose (5.5.3)

remove () est obsolète et vous pouvez utiliser deleteOne (), deleteMany () ou bulkWrite () à la place.

Dès que "mongoose": ">=2.7.1"vous pouvez supprimer le document directement avec la .remove()méthode plutôt que de trouver le document puis de le supprimer ce qui me semble plus efficace et plus facile à entretenir.

Voir l'exemple:

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

METTRE À JOUR:

Comme pour la mangouste 3.8.1, il existe plusieurs méthodes qui vous permettent de supprimer directement un document, par exemple:

  • remove
  • findByIdAndRemove
  • findOneAndRemove

Reportez-vous à la documentation de l'API mangouste pour plus d'informations.


13
Comme indiqué dans d'autres commentaires à d'autres réponses, ce contournement du middleware qui est défini sur le schéma, et peut être vraiment dangereux. Ne l'utilisez donc que si vous comprenez l'impact que cela aura. Pour plus d'informations, voir mongoosejs.com/docs/middleware.html
Jed Watson

2
Juste pour mémoire, jusqu'à présent, je les ai toujours utilisés sans aucun effet secondaire, bien sûr, je ne devais pas utiliser de middleware dans mes projets :)
diosney

8
remove(query)pourrait potentiellement vider votre collection entière si vous passez accidentellement query = {}. Pour cette raison, je préfère findOneAndRemove(query)que je retire un seul document.
joeytwiddle

1
Notez également que cela ne renvoie pas de requête, donc ni une promesse. Vous ne pouvez pas faireModel.remove({ _id: 'whatever' }).exec().then(...)
David

48

docsest un tableau de documents. il n'a donc pas de mongooseModel.remove()méthode.

Vous pouvez parcourir et supprimer chaque document du tableau séparément.

Ou - puisqu'il semble que vous trouviez les documents par un identifiant (probablement) unique - utilisez findOneplutôt que find.


5
Étant donné que cette réponse suppose une version plutôt ancienne de la mangouste, je ne m'opposerais vraiment pas à ce que quelqu'un modifie la réponse acceptée.
mtkopone

C'est en fait l'un des meilleurs moyens de le faire car il appelle correctement le middleware défini sur le schéma - voir mongoosejs.com/docs/middleware.html . Vous ne devez utiliser les autres méthodes que si vous n'utilisez PAS de middleware dans votre application, puis avec prudence.
Jed Watson

41

Pour moi, c'est le meilleur de la version 3.8.1:

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

Et cela ne nécessite qu'un seul appel DB. Utilisez ceci étant donné que vous n'effectuez aucune removeaction avant la recherche et la suppression.


1
Tant que vous n'avez pas besoin d'effectuer des pre 'remove'actions, cela fonctionne bien.
Daniel Kmak

32

Faites simplement

FBFriendModel.remove().exec();

1
Simple et efficace.
Rich Apodaca

1
Est-ce que cela retourne une promesse? Si oui, quel objet est défini lorsque la promesse est résolue?
Kenny Worden

@KennyWorden une approche efficace pour trouver la réponse -> mongoosejs.com/docs/api.html puis recherchez ce que vous voulez mais ajoutez «#» à la recherche sur la page avec votre navigateur, comme la recherche sur «#save» et vous 'll verra qu'il retourne une promesse.
Jason Sebring

3
C'est une sorte de réponse dangereuse sans mettre la condition op spécifiée dans la suppression ...
blak3r

29

mongoose.model.find()renvoie un objet de requête qui a également unremove() fonction.

Vous pouvez également l'utiliser mongoose.model.findOne()si vous souhaitez supprimer un seul document unique.

Sinon, vous pouvez également suivre l'approche traditionnelle lorsque vous récupérez d'abord le document, puis le supprimez.

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

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

modelVous trouverez ci-dessous les méthodes permettant de supprimer un ou plusieurs documents sur un objet:

yourModelObj.findOneAndRemove(conditions, options, callback)

yourModelObj.findByIdAndRemove(id, options, callback)

yourModelObj.remove(conditions, callback);

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

22

remove()est obsolète. Utiliser deleteOne(), deleteMany()oubulkWrite() .

Le code que j'utilise

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

1
Honnêtement, cette réponse a besoin de plus de votes positifs. Il est injustement placé au fond du baril (car il n'a pas reçu une demi-décennie de votes archaïques), mais c'est la seule réponse qui résout le problème de:(node:9132) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
Steven Ventimiglia

18

Pour généraliser, vous pouvez utiliser:

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

Une autre façon d'y parvenir est:

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

18

Soyez prudent avec findOne et supprimez!

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

Le code ci-dessus supprime TOUS les utilisateurs nommés «Alice» au lieu du premier uniquement.

Soit dit en passant, je préfère supprimer des documents comme celui-ci:

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

Ou fournissez un rappel et omettez l'exec ()

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


12

Si vous recherchez un seul objet à supprimer, vous pouvez utiliser

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

    });

Dans cet exemple, Mongoose supprimera en fonction de la correspondance req.params.id.


Bienvenue sur Stackoverflow. Votre réponse est un double de plusieurs réponses dans ce fil. En outre, vous devez toujours vérifier l'absence d'erreur dans vos rappels.
VtoCorleone

9

.remove()fonctionne comme .find():

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

9

Je préfère la notation de promesse, où vous avez besoin, par exemple

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

7

Pour supprimer un document, je préfère utiliser Model.remove(conditions, [callback])

Veuillez consulter la documentation de l'API pour la suppression: -

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

Dans ce cas, le code sera: -

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

Si vous souhaitez supprimer des documents sans attendre une réponse de MongoDB, ne passez pas de rappel, alors vous devez appeler exec sur la requête retournée

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

6

Vous pouvez simplement utiliser la requête directement dans la fonction de suppression, donc:

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

6

Vous pouvez toujours utiliser la fonction intégrée 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

Mise à jour: .remove()est dépréciée mais cela fonctionne toujours pour les anciennes versions

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

Model.remove est obsolète
Maxwell sc

2

en utilisant la méthode remove () que vous pouvez supprimer.

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

Model.remove est obsolète
Maxwell sc

1
Maxwell sc, faites une demande d'édition puis corrigez. Je sais que vous êtes nouveau à SO, mais il est beaucoup plus utile de le réparer que de dire qu'il est déprécié. Peut-être pourriez-vous suggérer un montage la prochaine fois, ou faire un montage vous-même, et vous approprier un peu la situation ...
Joshua Michael Waggoner

1

Cela a fonctionné pour moi, essayez simplement ceci:

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 déconseillé
Maxwell sc

1

Selon la réponse de Samyak Jain, j'utilise Async Await

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

0

J'aime vraiment ce modèle dans les applications asynchrones / attendez Express / Mongoose:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.