Löschen Sie mit Mongoose einen Schlüssel aus einem MongoDB-Dokument


102

Ich verwende die Mongoose Library für den Zugriff auf MongoDB mit node.js.

Gibt es eine Möglichkeit , einen Schlüssel aus einem Dokument zu entfernen ? dh den Wert nicht nur auf null setzen, sondern entfernen?

User.findOne({}, function(err, user){
  //correctly sets the key to null... but it's still present in the document
  user.key_to_delete = null;

  // doesn't seem to have any effect
  delete user.key_to_delete;

  user.save();
});

1
Ich dachte, ich hätte es gefunden, aber nach einigen Tests: wahrscheinlich nicht. Dies hat jedoch einige gute Diskussionen zu diesem Thema. groups.google.com/group/mongoose-orm/browse_thread/thread/…
Stephen

LOL vergiss es, ich denke das war dein Beitrag!
Stephen

Antworten:


167

In früheren Versionen hätten Sie den Node-Mongodb-Native-Treiber löschen müssen. Jedes Modell verfügt über ein Sammlungsobjekt, das alle Methoden enthält, die Node-Mongodb-Native bietet. Sie können die betreffende Aktion also folgendermaßen ausführen:

User.collection.update({_id: user._id}, {$unset: {field: 1 }});

Seit Version 2.0 können Sie:

User.update({_id: user._id}, {$unset: {field: 1 }}, callback);

Und seit Version 2.4 können Sie Folgendes tun, wenn Sie bereits eine Instanz eines Modells haben:

doc.field = undefined;
doc.save(callback);

Dies wurde in Mongoose 2.X behoben, sodass Sie die Sammlung weglassen können.
staackuser2

4
Verwenden User.update({ _id: id }, { $unset: { field: 1 }}, callback)Sie entweder oder wenn Sie eine Dokumentinstanz haben, setzen Sie den Pfad auf undefiniert und speichern Sie ihn dann:doc.field = undefined; doc.save()
aaronheckmann

25
Nur eine Anmerkung, dass, wenn Sie versuchen, eine alte Eigenschaft zu entfernen, die nicht mehr in Ihrem Schema definiert ist, Sie tun müssendoc.set('field', undefined)
evilcelery

3
Was ist mit Löschen doc.field.foo?
Chovy

28
@evilcelery reicht doc.set('field', undefined)möglicherweise nicht aus, da im strengen Modus (Standard) keine Felder mehr festgelegt werden können, die nicht mehr im Schema enthalten sind. doc.set('field', undefined, { strict: false })hat gut funktioniert.
Alexander Link


30

Ich benutze Mungo und mit einer der oben genannten Funktionen habe ich die Anforderung erfüllt. Die Funktion kompiliert fehlerfrei, aber das Feld bleibt weiterhin erhalten.

user.set('key_to_delete', undefined, {strict: false} );

hat den Trick für mich gemacht.


Das Upvoting dieser nützlichen Antwort, schade @ alexander-link, machte es 2015 nicht zu einer Antwort ( stackoverflow.com/questions/4486926/… )
w00t

1
Vielen Dank für Ihre Antwort. Für mich haben die anderen Lösungen für in Arrays verschachtelte Objekte nicht funktioniert!
BenSower

@ BenSower Das war auch mein Fall. Nur diese Lösung funktionierte gut, da ich ein Feld mit Array löschen musste, nachdem ich die ID eines bestimmten Dokuments gefunden hatte
Luis Febro

Beachten Sie, dass die Zeichenfolge ein Pfad zum Schlüssel ist. Wenn das zu löschende Objekt verschachtelt ist, müssen Sie einen Pfad dazu erstellen. Diese Antwort hat mein Problem gelöst!
Bradyo

8

Bei der Mongo-Syntax müssen Sie Folgendes tun, um einen Schlüssel zu löschen:

{ $unset : { field : 1} }

Scheint bei Mongoose das gleiche.

Bearbeiten

Überprüfen Sie dieses Beispiel.


Können Sie diese Antwort klarstellen und ein Codebeispiel angeben, das sich auf den obigen Beispielcode bezieht?
Daniel Beardsley

Entschuldigung, aber ich bin nicht mit Mungo vertraut. Über der Syntax ist es Mongo-Syntax, also nehme ich an, dass der Treiber für jede Sprache dies unterstützt. Ich habe ein Beispiel gefunden, überprüfen Sie es in meiner Antwort.
Andrew Orsich

1

Könnte dies ein Nebenproblem wie bei der Verwendung sein

function (user)

anstatt

function(err, user)

für den Rückruf des Funds? Ich versuche nur dabei zu helfen, da ich den Fall bereits hatte.


1

Mungodokument ist KEIN einfaches Javascript-Objekt und deshalb können Sie den Löschoperator nicht verwenden (oder unsetaus der 'lodash'-Bibliothek).

Sie können doc.path = null || setzen undefined oder verwenden Sie die Document.toObject () -Methode, um das Mungodokument in ein einfaches Objekt umzuwandeln und von dort aus wie gewohnt zu verwenden. Lesen Sie mehr in mongoose api-ref: http://mongoosejs.com/docs/api.html#document_Document-toObject

Beispiel würde ungefähr so ​​aussehen:

User.findById(id, function(err, user) {
    if (err) return next(err);
    let userObject = user.toObject();
    // userObject is plain object
});

1

Versuchen:

User.findOne({}, function(err, user){
  // user.key_to_delete = null; X
  `user.key_to_delete = undefined;`

  delete user.key_to_delete;

  user.save();
});

0

Das Problem bei all diesen Antworten ist, dass sie für ein Feld funktionieren. Angenommen, ich möchte alle Felder aus meinem Dokument löschen, wenn sie eine leere Zeichenfolge sind "". Zuerst sollten Sie prüfen , ob Feld leere Zeichenfolge es zu setzen $unset:

function unsetEmptyFields(updateData) {
  const $unset = {};
  Object.keys(updatedData).forEach((key) => {
    if (!updatedData[key]) {
      $unset[key] = 1;
      delete updatedData[key];
    }
  });
  updatedData.$unset = $unset;

  if (isEmpty(updatedData.$unset)) { delete updatedData.$unset; }

  return updatedData;
}

function updateUserModel(data){
const updatedData = UnsetEmptyFiled(data);

    const Id = "";
    User.findOneAndUpdate(
      { _id: Id },
      updatedData, { new: true },
    );
}

0

Wenn Sie einen Schlüssel aus der Sammlung entfernen möchten, versuchen Sie diese Methode. das hat bei mir funktioniert

 db.getCollection('myDatabaseTestCollectionName').update({"FieldToDelete": {$exists: true}}, {$unset:{"FieldToDelete":1}}, false, true);

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.