Elimina una chiave da un documento MongoDB utilizzando Mongoose


103

Sto usando la libreria Mongoose per accedere a MongoDB con node.js

C'è un modo per rimuovere una chiave da un documento ? cioè non basta impostare il valore su null, ma rimuoverlo?

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
Pensavo di averlo trovato, ma dopo alcuni test: probabilmente no. Tuttavia, questo ha alcune buone discussioni sull'argomento. groups.google.com/group/mongoose-orm/browse_thread/thread/…
Stephen

LOL non importa, immagino che questo fosse il tuo post!
Stephen

Risposte:


168

Nelle prime versioni, sarebbe stato necessario eliminare il driver node-mongodb-native. Ogni modello ha un oggetto di raccolta che contiene tutti i metodi offerti da node-mongodb-native. Quindi puoi eseguire l'azione in questione in questo modo:

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

Dalla versione 2.0 puoi fare:

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

E dalla versione 2.4, se hai già un'istanza di un modello puoi fare:

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

Questo problema è stato risolto in Mongoose 2.X, quindi puoi lasciare fuori la raccolta.
staackuser2

4
Utilizzare User.update({ _id: id }, { $unset: { field: 1 }}, callback)o se si dispone di un'istanza del documento, impostare il percorso su undefined e quindi salvarlo:doc.field = undefined; doc.save()
aaronheckmann

25
Solo una nota che se stai cercando di rimuovere una vecchia proprietà che non è più definita nel tuo schema devi faredoc.set('field', undefined)
evilcelery

3
che dire dell'eliminazione doc.field.foo?
chovy

28
@evilcelery doc.set('field', undefined)potrebbe non essere sufficiente poiché la modalità rigorosa (predefinita) non consente di impostare campi che non sono più nello schema. doc.set('field', undefined, { strict: false })ha funzionato bene.
Alexander Link


30

Io uso mangusta e l'utilizzo di una qualsiasi delle funzioni di cui sopra mi ha fatto il requisito. La funzione compila senza errori ma il campo rimarrebbe comunque.

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

ha fatto il trucco per me.


Upvoting questa risposta utile, peccato @ alexander-link non ce l'ha fatta di nuovo una risposta nel 2015 ( stackoverflow.com/questions/4486926/... )
w00t

1
Grazie per la tua risposta, per me, le altre soluzioni non hanno funzionato per gli oggetti annidati negli array!
BenSower

@ BenSower Questo è stato anche il mio caso. Solo questa soluzione ha funzionato bene perché ho dovuto eliminare un campo con array dopo aver trovato l'ID di un documento specifico
Luis Febro

Notare che la stringa è un percorso per la chiave. Quindi, se l'oggetto che vuoi eliminare è nidificato, devi tracciarlo. Questa risposta ha risolto il mio problema!
Bradyo

8

Alla sintassi mongo per eliminare alcune chiavi è necessario eseguire le seguenti operazioni:

{ $unset : { field : 1} }

A Mangusta sembra lo stesso.

modificare

Controlla questo esempio.


Puoi chiarire questa risposta e fornire un esempio di codice correlato al codice di esempio sopra?
Daniel Beardsley

scusate ma non sono esperto di mangusta. Sopra la sintassi è la sintassi mongo, quindi suppongo che il driver per qualsiasi linguaggio lo supporti. Ho trovato qualche esempio, controllalo nella mia risposta.
Andrew Orsich

1

Potrebbe essere un problema secondario come l'utilizzo di

function (user)

invece di

function(err, user)

per la richiamata del ritrovamento? Sto solo cercando di aiutare con questo perché avevo già il caso.


1

Il documento Mongoose NON è un semplice oggetto javascript ed è per questo che non è possibile utilizzare l'operatore di cancellazione (o unsetdalla libreria 'lodash').

Le tue opzioni sono di impostare doc.path = null || undefined o utilizzare il metodo Document.toObject () per trasformare mongoose doc in un oggetto semplice e da lì usarlo come al solito. Maggiori informazioni in mongoose api-ref: http://mongoosejs.com/docs/api.html#document_Document-toObject

L'esempio sarebbe simile a questo:

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

1

Provare:

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

  delete user.key_to_delete;

  user.save();
});

0

il problema con tutte queste risposte è che funzionano per un campo. per esempio diciamo che voglio eliminare tutti i campi dal mio documento se fossero una stringa vuota "". Per prima cosa dovresti controllare se il campo è una stringa vuota metterlo in $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

se vuoi rimuovere una chiave dalla raccolta prova questo metodo. questo ha funzionato per me

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.