Wie entferne ich Dokumente mit Node.js Mongoose?

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

Das obige scheint nicht zu funktionieren. Die Aufzeichnungen sind noch da.

Kann jemand reparieren?

TIMEX
quelle

Antworten:

489

Wenn Sie keine Lust zum Iterieren haben, versuchen Sie es FBFriendModel.find({ id:333 }).remove( callback );oderFBFriendModel.find({ id:333 }).remove().exec();

mongoose.model.findgibt eine Abfrage zurück , die eine removeFunktion hat .

Update für Mongoose v5.5.3 - remove()ist jetzt veraltet. Verwendung deleteOne(), deleteMany()oderfindOneAndDelete() instead.

Yusuf X.
quelle
3
Läuft diese Middleware vor / nach dem Entfernen? (Einige Modellmethoden umgehen die Dokument-Middleware und ich bin nicht sicher, ob dies eine davon ist. Die Dokumente sind unklar.)
hunterloftis
12
Ich nehme an, @hunterloftis hat dies bereits herausgefunden, aber für alle anderen, die die Antwort Nein lesen, wird keine Pre / Post-Middleware für einzelne Dokumente ausgeführt.
Nummern 1311407
Dies scheint, dass viele der anderen Antworten dies erwähnen, dies .exec()jedoch überhaupt nicht. Wird .exec()benötigt, gibt es Nebenwirkungen bei der Verwendung oder nicht?
DanH
In den Dokumenten ist klar (möglicherweise wurden sie aktualisiert), dass dies die Middleware umgeht (siehe unten in mongoosejs.com/docs/middleware.html). Seien Sie also vorsichtig, wenn Sie diese Methode verwenden, kann dies zu ernsthaften, schwer auffindbaren Problemen führen.
Jed Watson
1
gute Antwort! Was sind die Argumente des Rückrufs?
k88074
299

UPDATE: Mungo-Version (5.5.3)

remove () ist veraltet und Sie können stattdessen deleteOne (), deleteMany () oderulkWrite () verwenden.

Ab "mongoose": ">=2.7.1"sofort können Sie das Dokument direkt mit der .remove()Methode entfernen , anstatt das Dokument zu finden und dann zu entfernen, was mir effizienter und einfacher zu warten erscheint.

Siehe Beispiel:

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

AKTUALISIEREN:

Ab Mungo 3.8.1gibt es verschiedene Methoden, mit denen Sie ein Dokument direkt entfernen können, z. B.:

  • remove
  • findByIdAndRemove
  • findOneAndRemove

Weitere Informationen finden Sie in den API-Dokumenten für Mungos .

Diosney
quelle
13
Wie in anderen Kommentaren zu anderen Antworten erwähnt, umgeht dies die im Schema definierte Middleware und kann sehr gefährlich sein. Verwenden Sie es also nur, wenn Sie die Auswirkungen verstehen, die sich daraus ergeben werden. Weitere Informationen finden Sie unter mongoosejs.com/docs/middleware.html
Jed Watson
2
Nur zur Veranschaulichung, bis jetzt habe ich sie immer ohne Nebenwirkungen verwendet, sicher, ich musste keine Middleware in meinen Projekten verwenden :)
Diosney
8
remove(query)könnte möglicherweise Ihre gesamte Sammlung leeren, wenn Sie versehentlich passieren query = {}. Aus diesem Grund bevorzuge ich es, findOneAndRemove(query)wenn ich nur ein Dokument entferne .
Joeytwiddle
1
Beachten Sie auch, dass dies keine Abfrage zurückgibt, also auch kein Versprechen. Sie können nicht tunModel.remove({ _id: 'whatever' }).exec().then(...)
David
48

docsist eine Reihe von Dokumenten. Es gibt also keine mongooseModel.remove()Methode.

Sie können jedes Dokument im Array separat iterieren und entfernen.

Oder - da es so aussieht, als würden Sie die Dokumente anhand einer (wahrscheinlich) eindeutigen ID finden - verwenden Sie findOnestatt find.

mtkopone
quelle
5
Da diese Antwort eine ziemlich alte Version von Mungo voraussetzt, würde ich wirklich nichts dagegen haben, dass jemand die akzeptierte Antwort ändert.
Mtkopone
Dies ist tatsächlich eine der besten Möglichkeiten, da die im Schema definierte Middleware korrekt aufgerufen wird - siehe mongoosejs.com/docs/middleware.html . Sie sollten die anderen Methoden nur verwenden, wenn Sie in Ihrer Anwendung KEINE Middleware verwenden, und dies dann mit Vorsicht.
Jed Watson
41

Dies ist für mich das Beste ab Version 3.8.1:

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

Und es ist nur ein DB-Aufruf erforderlich. Verwenden Sie diese removeOption, da Sie vor dem Suchen und Entfernen keine Aktionen ausführen.

José Pinto
quelle
1
Solange Sie keine pre 'remove'Aktionen ausführen müssen, funktioniert es einwandfrei.
Daniel Kmak
32

Einfach machen

FBFriendModel.remove().exec();
Sandro Munda
quelle
1
Einfach und effektiv.
Rich Apodaca
1
Gibt dies ein Versprechen zurück? Wenn ja, welches Objekt wird definiert, wenn das Versprechen aufgelöst wird?
Kenny Worden
@KennyWorden einen effektiven Ansatz , um die Antwort zu finden -> mongoosejs.com/docs/api.html suchen Sie dann nach , was Sie wollen , aber prepend ‚#‘ auf die in-Seite Suche mit Ihrem Browser wie Suche auf ‚#save‘ und Sie Ich werde sehen, dass es ein Versprechen zurückgibt.
Jason Sebring
3
Dies ist eine Art gefährliche Antwort, ohne die Bedingung zu setzen, die in der Entfernung angegeben ist ...
blak3r
29

mongoose.model.find()Gibt ein Abfrageobjekt zurück, das auch eine remove()Funktion hat.

Sie können auch verwenden mongoose.model.findOne(), wenn Sie nur ein eindeutiges Dokument entfernen möchten.

Andernfalls können Sie auch dem traditionellen Ansatz folgen, bei dem Sie zuerst das Dokument abrufen und dann entfernen.

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

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

Im Folgenden finden modelSie die folgenden Möglichkeiten für Objekte, um Dokumente zu entfernen:

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
quelle
22

remove()wurde veraltet. Verwenden Sie deleteOne(), deleteMany()oder bulkWrite().

Der Code, den ich benutze

TeleBot.deleteMany({chatID: chatID}, function (err, _) {
                if (err) {
                    return console.log(err);
                }
            });
Samyak Jain
quelle
1
Diese Antwort braucht ehrlich gesagt mehr Gegenstimmen. Es ist unfair am Boden des Fasses platziert (weil es kein halbes Jahrzehnt antiquierter Stimmen erhalten hat), aber es ist die einzige Antwort, die das Problem löst:(node:9132) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
Steven Ventimiglia
18

Zur Verallgemeinerung können Sie verwenden:

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

Ein anderer Weg, dies zu erreichen, ist:

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

Seien Sie vorsichtig mit findOne und entfernen Sie!

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

Der obige Code entfernt ALLE Benutzer mit dem Namen "Alice" anstelle des ersten .

Übrigens ziehe ich es vor, Dokumente wie diese zu entfernen:

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

Oder geben Sie einen Rückruf ein und lassen Sie exec () weg

  User.remove({...}, callback);
Damphat
quelle
12

Wenn Sie nur ein zu entfernendes Objekt suchen, können Sie es verwenden

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

    });

In diesem Beispiel wird Mongoose basierend auf der Übereinstimmung mit req.params.id gelöscht.

Bhavsac
quelle
Willkommen bei Stackoverflow. Ihre Antwort ist ein Duplikat mehrerer Antworten in diesem Thread. Außerdem sollten Sie Ihre Rückrufe immer auf Fehler überprüfen.
VtoCorleone
9

.remove()funktioniert wie .find():

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

Ich bevorzuge die Versprechensnotation, wo Sie zB brauchen

Model.findOneAndRemove({_id:id})
    .then( doc => .... )
Simon H.
quelle
7

Zum Entfernen von Dokumenten bevorzuge ich die Verwendung Model.remove(conditions, [callback])

Informationen zum Entfernen finden Sie in der API-Dokumentation: -

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

In diesem Fall lautet der Code: -

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

Wenn Sie Dokumente entfernen möchten, ohne auf eine Antwort von MongoDB zu warten, keinen Rückruf übergeben, müssen Sie exec für die zurückgegebene Abfrage aufrufen

var removeQuery = FBFriendModel.remove({id : 333 });
removeQuery.exec();
Satyam Kumar
quelle
6

Sie können die Abfrage einfach direkt in der Entfernungsfunktion verwenden, also:

FBFriendModel.remove({ id: 333}, function(err){});
David Losert
quelle
6

Sie können immer die integrierte Funktion Mongoose verwenden:

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
quelle
5

Update: .remove()wird abgeschrieben, funktioniert aber immer noch für ältere Versionen

YourSchema.remove({
    foo: req.params.foo
}, function(err, _) {
    if (err) return res.send(err)
    res.json({
        message: `deleted ${ req.params.foo }`
    })
});
Joshua Michael Waggoner
quelle
Model.remove ist veraltet
Maxwell sc
2

Mit der Methode remove () können Sie entfernen.

getLogout(data){
        return this.sessionModel
        .remove({session_id: data.sid})
        .exec()
        .then(data =>{
            return "signup successfully"
        })
    }
KARTHIKEYAN.A
quelle
Model.remove ist veraltet
Maxwell sc
1
Maxwell sc, stellen Sie dann eine Bearbeitungsanforderung und korrigieren Sie. Ich weiß, dass Sie SO noch nicht kennen, aber es ist viel hilfreicher, das Problem zu beheben, als zu kommentieren, dass es abgeschrieben ist. Vielleicht könnten Sie beim nächsten Mal eine Änderung vorschlagen oder selbst eine Änderung vornehmen und ein wenig Verantwortung für die Situation übernehmen ...
Joshua Michael Waggoner
1

Das hat bei mir funktioniert, versuchen Sie es einfach:

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
quelle
Model.removeist veraltet
Maxwell sc
1

Gemäß der Antwort von Samyak Jain verwende ich Async Await

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

Ich mag dieses Muster in asynchronen / wartungsfähigen Express / Mongoose-Apps sehr:

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
quelle
-2
db.collection.remove(<query>,
 {
  justOne: <boolean>,
  writeConcern: <document>
})
Rushabh.js
quelle
@ MR: Wie kann es nur Link sein, wenn die Antwort keinen Link enthält? Überprüfen Sie auch: Beiträge von geringer Qualität und nur Code-Antworten
BDL
Sry Fehlklick. Ist aber immer noch eine geringe Qualität.
MR