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();
});
Daniel Beardsley
quelle
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);
staackuser2
quelle
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
56

Sie möchten dies tun:

User.findOne({}, function(err, user){
  user.key_to_delete = undefined;
  user.save();
});
deedubs
quelle
3
Das wird es einfach auf null setzen - nicht das, was das OP verlangt.
Ian Henry
25
Ab Version 2.4.0 wird durch Festlegen eines Dokumentschlüssels auf undefiniert das $ unset an mongodb aaronheckmann.posterous.com/mongoose-240
James Moore am
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.

Noushad
quelle
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.

Andrew Orsich
quelle
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.

Luc
quelle
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
});
Petarr
quelle
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();
});
Jeisson Valderrama
quelle
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 },
    );
}
Milad Ranjbar
quelle
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);
Bivin Vinod
quelle
-4

Sie können delete user._doc.key verwenden

Joel Esperanza
quelle