Як перетворити документ мангуста в звичайний об’єкт?


200

У мене є документ від мангуста, який я хочу розширити перед кодуванням JSON та надсиланням як відповідь. Якщо я спробую додати властивості до документа, він ігнорується. Властивості не відображаються, Object.getOwnPropertyNames(doc)коли зробити звичайне розширення неможливо. Дивне те, що JSON.parse(JSON.encode(doc))працює і повертає об’єкт з усіма правильними властивостями. Чи є кращий спосіб зробити це?

Відповіді:


292

Мангусти Models успадковують від Documents, у яких є toObject()метод. Я вважаю, що те, що ви шукаєте, повинно бути результатом doc.toObject().

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


1
нарешті дістався. для тих, хто має невизначити об'єкт, обов'язково зателефонуйте на документ замість моделі. тобто modelName._doc.toObject ()
Джон

1
Це нормально, але віддається перевага ().
Джейсон Себрінг

Чи працює це, якщо ви повертаєте масив на Model.find({})документі return - це масив. Чи можете ви docs.toObject?
jack blank

5
@jackblank Якщо у вас є масив Моделі, ви повинні мати можливість відображати їх:var docArray = modelArray.map(function(model) { return model.toObject(); });
jmar777

@ jmar777 Я думаю, що ваша пропозиція належить до редагування цієї відповіді.
r3wt

200

Ще один спосіб зробити це - сказати Mongoose, що все, що вам потрібно, - це звичайна версія JavaScript повернутого документа за допомогою lean()ланцюга запитів. Таким чином Mongoose пропускає крок створення повного екземпляра моделі, і ви безпосередньо отримуєте docви можете змінювати:

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

16
@Startec Використання, leanяк правило, ефективніше, оскільки ви пропускаєте накладні витрати, перш ніж створити повний документ Мангуста.
JohnnyHK

3
ви чемпіон :) виправте мене, якщо я помиляюся, але ви завжди повинні нахилятися () свою знахідку (), якщо ви не збираєтесь змінювати та зберігати щойно отриманий документ (скажімо, якщо ви просто намагаєтесь отримати доступ до doc та відправте його своєму клієнту)
Amarsh,

1
@Amarsh Так, хоча це також передбачає, що вам не потрібен жоден із методів екземпляра або віртуалів, визначених у схемі.
JohnnyHK

1
bizzare, хоча ... це міг бути варіант з find () ... його часто занадто часто, щоб прочитати документ з mongodb і відправити його назад у веб-браузер. мені цікаво, якщо find (). lean () насправді означає спочатку find (), а потім застосувати lean () кожного елемента в результаті, і в цьому випадку комбінація find (). lean () насправді буде повільніше, ніж find () себе.
Амарш

4
@Amarsh Ні, ланцюжок lean()на запит встановлює параметр перед тим, як запит буде фактично виконаний (від exec), так що результати знаходяться безпосередньо в їх "худій" формі. Дивіться це питання для позитивного впливу на ефективність дзвінків lean.
JohnnyHK

29

швидкий шлях, якщо властивість відсутня в моделі:

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


5
так ... і як не дивно, як це здається, я все ще думаю, що це може бути корисним. Наприклад, ви зберігаєте всі примітиви вашого об'єкта.
alban maillere

Дякую за цю відповідь, саме це я шукав :)
datUser

6

Кращим способом вирішення подібної проблеми є використання doc.toObject()подібного

doc.toObject({ getters: true })

інші варіанти включають:

  • getters: застосувати всі геттери (шляхові та віртуальні)
  • virtuals: застосувати віртуальні геттери (може замінити параметр getters)
  • minimize: видалити порожні об’єкти (за замовчуванням до істинного)
  • transform: функція перетворення, яка застосовується до отриманого документа перед поверненням
  • depopulate: депопуляція будь-яких заселених шляхів, замінюючи їх оригінальними рефлексами (за замовчуванням на хибні)
  • versionKey: чи включати ключ версії (за замовчуванням до істинного)

так, наприклад, ви можете сказати

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

і тепер це буде працювати.

Для ознайомлення дивіться: http://mongoosejs.com/docs/api.html#document_Document-toObject


3

Щоб отримати звичайний об'єкт з документа Мангуста, я використовував _docвластивість наступним чином

mongooseDoc._doc  //returns plain json object

Я спробував, toObjectале це дало мені функції, аргументи та всі інші речі, які мені не потрібні.


3
Отримати доступ до властивостей або методів _на початку це не ідеальне рішення. Використання нахилу може вирішити вашу справу.
Артур Коста

@ArthurBrito так. Це не ідеальне рішення, але все-таки РІШЕННЯ! . Не потрібно спростовувати відповідь. Я користувався _docмайном багато разів, не стикаючись з жодним питанням. А використання leanметоду дає вам звичайний об'єкт, над яким ви не можете виконувати операції з мангустною моделлю.
dd619,

ти маєш рацію. Просто додайте у своїй відповіді, що це не ідеальне рішення, тоді я зніму нижчу заявку (я не можу видалити, якщо ви не відредагували)
Артур Коста,

2

Ви також можете об'єктивувати об'єкт і потім знову розібратися, щоб зробити звичайний об'єкт. Наприклад, як: -

const obj = JSON.parse(JSON.stringify(mongoObj))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.