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.