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();
});
Daniel Beardsley
źródło
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);
staackuser2
źródło
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
56

Będziesz chciał to zrobić:

User.findOne({}, function(err, user){
  user.key_to_delete = undefined;
  user.save();
});
deedubs
źródło
3
To po prostu ustawi go na zero - a nie to, o co prosi PO.
Ian Henry,
25
Począwszy od wersji 2.4.0 Ustawianie kluczowym dokumentem do niezdefiniowany minie $ rozbrojony do MongoDB aaronheckmann.posterous.com/mongoose-240
James Moore
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.

Noushad
źródło
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.

Andrew Orsich
źródło
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ę.

Luc
źródło
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
});
petarr
źródło
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();
});
Jeisson Valderrama
źródło
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 },
    );
}
Milad ranjbar
źródło
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);
Bivin Vinod
źródło
-4

możesz użyć delete user._doc.key

Joel Esperanza
źródło