Usuń klucz z dokumentu MongoDB za pomocą Mongoose


103

Używam biblioteki Mongoose do uzyskiwania dostępu do MongoDB z node.js.

Czy istnieje sposób na usunięcie klucza z dokumentu ? tj. nie tylko ustawić wartość na null, ale ją usunąć?

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
Myślałem, że go znalazłem, ale po kilku testach: prawdopodobnie nie. Jest to jednak dobra dyskusja na ten temat. groups.google.com/group/mongoose-orm/browse_thread/thread/…
Stephen

LOL nieważne, myślę, że to był twój post!
Stephen

Odpowiedzi:


168

We wczesnych wersjach trzeba by było usunąć sterownik node-mongodb-native. Każdy model ma obiekt kolekcji, który zawiera wszystkie metody oferowane przez node-mongodb-native. Możesz więc wykonać daną czynność w ten sposób:

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

Od wersji 2.0 możesz:

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

A od wersji 2.4, jeśli masz już instancję modelu, możesz:

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

Zostało to naprawione w Mongoose 2.X, więc możesz pominąć kolekcję.
staackuser2

4
Użyj User.update({ _id: id }, { $unset: { field: 1 }}, callback)lub jeśli masz instancję dokumentu, ustaw ścieżkę na undefined, a następnie zapisz ją:doc.field = undefined; doc.save()
aaronheckmann

25
Tylko uwaga, jeśli próbujesz usunąć starą właściwość, która nie jest już zdefiniowana w Twoim schemacie, musisz to zrobićdoc.set('field', undefined)
evilcelery

3
a co z usuwaniem doc.field.foo?
chovy

28
@evilcelery doc.set('field', undefined)może nie wystarczyć, ponieważ tryb ścisły (domyślny) nie pozwala na ustawienie pól, których nie ma już w schemacie. doc.set('field', undefined, { strict: false })działało dobrze.
Alexander Link


30

Używam mangusty i użycie którejkolwiek z powyższych funkcji spełniło moje wymagania. Funkcja kompiluje się bez błędów, ale pole nadal pozostaje.

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

załatwił sprawę dla mnie.


Głosowanie za tą przydatną odpowiedzią, szkoda, @ alexander-link nie dało odpowiedzi w 2015 roku ( stackoverflow.com/questions/4486926/… )
w00t

1
Dziękuję za odpowiedź, dla mnie inne rozwiązania nie działały dla obiektów zagnieżdżonych w tablicach!
BenSower

@BenSower To też był mój przypadek. Tylko to rozwiązanie działało dobrze, ponieważ musiałem usunąć pole z tablicą po znalezieniu identyfikatora konkretnego dokumentu
Luis Febro

Zwróć uwagę, że ciąg jest ścieżką do klucza. Tak więc, jeśli obiekt, który chcesz usunąć, jest zagnieżdżony, musisz przejść do niego. Ta odpowiedź rozwiązała mój problem!
Bradyo

8

W składni mongo, aby usunąć jakiś klucz, wykonaj następujące czynności:

{ $unset : { field : 1} }

Wydaje się, że w Mongoose to samo.

Edytować

Sprawdź ten przykład.


Czy możesz wyjaśnić tę odpowiedź i podać przykładowy kod, który odnosi się do powyższego przykładowego kodu?
Daniel Beardsley,

przepraszam, ale nie mam doświadczenia w mangusta. Powyżej składni jest to składnia mongo, więc przypuszczam, że ten sterownik dla dowolnego języka to obsługuje. Znalazłem jakiś przykład, sprawdź to w mojej odpowiedzi.
Andrew Orsich,

1

Czy może to być problem uboczny, taki jak używanie

function (user)

zamiast

function(err, user)

do oddzwonienia do znaleziska? Po prostu próbuję w tym pomóc, ponieważ już miałem tę sprawę.


1

Dokument Mongoose NIE jest zwykłym obiektem javascript i dlatego nie możesz użyć operatora usuwania (lub unsetz biblioteki 'lodash').

Twoje opcje to ustawienie doc.path = null || undefined lub użyć metody Document.toObject (), aby zamienić dokument mongoose w zwykły obiekt, a następnie użyć go jak zwykle. Przeczytaj więcej w mongoose api-ref: http://mongoosejs.com/docs/api.html#document_Document-toObject

Przykład wyglądałby mniej więcej tak:

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

1

Próbować:

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

  delete user.key_to_delete;

  user.save();
});

0

Problem z tymi wszystkimi odpowiedziami polega na tym, że dotyczą one jednej dziedziny. na przykład, powiedzmy, że chcę usunąć wszystkie pola z mojego dokumentu, jeśli są one pustym ciągiem "". Najpierw sprawdź, czy pole jest puste, wpisz do $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

jeśli chcesz usunąć klucz z kolekcji, wypróbuj tę metodę. to działało dla mnie

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.