Jak zmienić dokument Mongoose w zwykły obiekt?


200

Mam dokument z znaleziska mangusty, który chcę rozszerzyć przed kodowaniem JSON i wysłaniem w odpowiedzi. Jeśli spróbuję dodać właściwości do dokumentu, zostanie to zignorowane. Właściwości nie pojawiają się w przypadku Object.getOwnPropertyNames(doc)niemożności normalnego rozszerzenia. Dziwne jest to, że JSON.parse(JSON.encode(doc))działa i zwraca obiekt o wszystkich poprawnych właściwościach. Czy jest na to lepszy sposób?

Odpowiedzi:


292

Mongoose Models dziedziczy po Documents, które mają toObject()metodę. Uważam, że to, czego szukasz, powinno być wynikiem doc.toObject().

http://mongoosejs.com/docs/api.html#document_Document-toObject


1
nareszcie to zdobyłem. dla tych, którzy muszą zdefiniować obiekt niezdefiniowany, pamiętaj o wywołaniu dokumentu zamiast modelu. tzn. modelName._doc.toObject ()
— John

1
Jest to OK, ale preferowane jest lean ().
— Jason Sebring

Czy to działa, jeśli zwrócisz tablicę po Model.find({})powrocie dokumentów to tablica. Czy umiesz docs.toObject?
— jack blank

5
@jackblank, jeśli masz szereg modeli, powinieneś być w stanie zmapować je:var docArray = modelArray.map(function(model) { return model.toObject(); });
— jmar777

@ jmar777 Myślę, że twoja sugestia należy do edycji tej odpowiedzi.
— r3wt

200

Innym sposobem na to jest poinformowanie Mongoose, że wszystko, czego potrzebujesz, to zwykła wersja JavaScript zwróconego dokumentu za pomocą lean()łańcucha zapytań. W ten sposób Mongoose pomija etap tworzenia pełnej instancji modelu i otrzymujesz bezpośrednio docmodyfikację:

MyModel.findOne().lean().exec(function(err, doc) {
    doc.addedProperty = 'foobar';
    res.json(doc);
});

16
@Startec Korzystanie leanjest na ogół bardziej wydajne, ponieważ pomijasz narzut związany z pierwszym tworzeniem pełnego dokumentu Mongoose.
— JohnnyHK

3
jesteś mistrzem :) popraw mnie, jeśli się mylę, ale zawsze powinieneś pochylić () swoje znaleziska (), jeśli nie zamierzasz modyfikować i zapisywać właśnie otrzymanego dokumentu (powiedz, jeśli próbujesz uzyskać dostęp do dok. i odeślij go do klienta)
— Amarsh

1
@Amarsh Tak, choć zakłada to również, że nie potrzebujesz żadnych metod instancji ani wirtualnych zdefiniowanych w schemacie.
— JohnnyHK

1
bizzare ... może to być opcja z find () ... często zbyt często czyta dokument z mongodb i odsyła go z powrotem do przeglądarki internetowej. zastanawiam się, czy find (). lean () faktycznie oznacza najpierw find (), a następnie zastosuj lean () każdego elementu w wyniku, w którym to przypadku kombinacja find (). lean () byłaby wolniejsza niż find () samo.
— Amarsh

4
@Amarsh Nie, łączenie łańcuchowe lean()w zapytaniu ustawia opcję przed wykonaniem (przez exec) zapytania, dzięki czemu wyniki są bezpośrednio w „ubogiej” formie. Zobacz to pytanie, aby poznać pozytywny wpływ połączeń na wydajność lean.
— JohnnyHK,

29

szybki sposób, jeśli właściwość nie znajduje się w modelu:

document.set( key,value, { strict: false });


5
tak ... i choć może to wydawać się zaskakujące, nadal uważam, że to może być przydatne. Na przykład zachowujesz wszystkie prymitywy obiektu.
— alban maillere

Dzięki za tę odpowiedź, właśnie tego szukałem :)
— datUser

6

Lepszym sposobem rozwiązania takiego problemu jest użycie doc.toObject()tego w ten sposób

doc.toObject({ getters: true })

inne opcje obejmują:

  • getters: zastosuj wszystkie metody pobierające (ścieżkę i metody pobierające wirtualne)
  • virtuals: zastosuj wirtualne operacje pobierania (może zastąpić opcję pobierania)
  • minimize: usuń puste obiekty (domyślnie true)
  • transform: funkcja przekształcania stosowana do dokumentu wynikowego przed zwróceniem
  • depopulate: wyludnij wszystkie zapełnione ścieżki, zastępując je oryginalnymi referencjami (domyślnie false)
  • versionKey: czy dołączyć klucz wersji (domyślnie true)

więc na przykład możesz powiedzieć

Model.findOne().exec((err, doc) => {
   if (!err) {
      doc.toObject({ getters: true })
      console.log('doc _id:', doc._id)
   }
})

i teraz będzie działać.

W celach informacyjnych patrz: http://mongoosejs.com/docs/api.html#document_Document-toObject


3

Aby uzyskać zwykły obiekt z dokumentu Mongoose, użyłem _docwłaściwości w następujący sposób

mongooseDoc._doc  //returns plain json object

Próbowałem, toObjectale dało mi to funkcje, argumenty i wszystkie inne rzeczy, których nie potrzebuję.


3
Dostęp do właściwości lub metod _na początku nie jest idealnym rozwiązaniem. Korzystanie z lean może rozwiązać twoją sprawę.
— Arthur Costa

@ArthurBrito tak. To nie jest idealne rozwiązanie, ale wciąż ROZWIĄZANIE! . Nie trzeba głosować za odpowiedzią. Korzystałem z _docnieruchomości wiele razy bez żadnych problemów. A użycie leanmetody daje prosty obiekt, na którym nie można wykonywać operacji na modelu mangusty.
— dd619,

masz rację. Wystarczy dodać w odpowiedzi, że nie jest to idealne rozwiązanie, a następnie usunę głos negatywny (nie mogę go usunąć, chyba że byłeś edytowany)
— Arthur Costa

2

Możesz także skreślić obiekt, a następnie ponownie przeanalizować, aby utworzyć normalny obiekt. Na przykład:

const obj = JSON.parse(JSON.stringify(mongoObj))
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.