У меня есть документ из mongoose find, который я хочу продлить до кодирования JSON и отправить в качестве ответа. Если я попробую добавить свойства в документ, он будет проигнорирован. Свойства не отображаются в Object.getOwnPropertyNames(doc)
, что делает невозможным нормальную протяженность. Странно, что JSON.parse(JSON.encode(doc))
работает и возвращает объект со всеми правильными свойствами. Есть ли лучший способ сделать это?
Как вы превращаете документ Mongoose в простой объект?
Ответ 1
Mongoose Model
наследует от Document
s, которые имеют метод toObject()
. Я считаю, что то, что вы ищете, должно быть результатом doc.toObject()
.
http://mongoosejs.com/docs/api.html#document_Document-toObject
Ответ 2
Другой способ сделать это - сказать Mongoose, что все, что вам нужно, это простая версия JavaScript возвращенного документа с помощью lean()
в цепочке запросов. Таким образом Mongoose пропускает шаг создания полного экземпляра модели, и вы непосредственно получаете doc
, который вы можете изменить:
MyModel.findOne().lean().exec(function(err, doc) {
doc.addedProperty = 'foobar';
res.json(doc);
});
Ответ 3
быстрый способ, если свойство не находится в модели:
document.set( key,value, { strict: false });
Ответ 4
Лучшим способом решения такой проблемы является использование doc.toObject()
подобного этому
doc.toObject({ getters: true })
другие варианты включают в себя:
-
getters:
применить все получатели (путь и виртуальные получатели) -
virtuals:
применять виртуальныеvirtuals:
получения (можно переопределить параметр получения) -
minimize:
удалить пустые объекты (по умолчанию true) -
transform:
функция transform для применения к результирующему документу перед возвратом -
depopulate:
удалить все заполненные пути, заменив их исходными ссылками (по умолчанию false) -
versionKey:
включать ли ключ версии (по умолчанию true)
так, например, вы можете сказать,
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
Ответ 5
Я удивлен, что никто не упомянул метод lean(). В результате он возвращает простой объект javascript вместо модели. мангуст худой()
Ответ 6
Удобный способ - применить его прямо к схеме модели.
Как указано в документации Mongoose:
"Чтобы применить эти параметры к каждому документу вашей схемы по умолчанию, задайте для параметра toObject схемы один и тот же аргумент".
schema.set('toObject', { virtuals: true })
Ответ 7
Чтобы получить простой объект из документа Mongoose, я использовал свойство _doc
следующим образом
mongooseDoc._doc //returns plain json object
Я пытался с toObject
, но он дал мне функции, аргументы и все остальное, что мне не нужно.
Ответ 8
С Typescript и lodash, я сделал следующее:
_.assign<IUser>({}, doc)
где IUser
- определение класса или интерфейса, а doc - базовый документ, определенный ниже.
interface UserDoc extends IUser, mongoose.Document { }
В случаях, когда свойства не совсем совпадают, я создаю статический метод
static castUserDoc(doc: UserDoc): $User { // ++
const result: any = _.assign({}, doc); // any is necessary to abandon type inferencing
result.prop = _.keyBy(result.prop, '_id'); // +++
return <$User>result; // cast back into type safety
}
++ Обратите внимание, что
IUser
и$User
отличаются+++
prop
- это карта на$User
, но массив наIUser
выполняется следующим образом:
const user: $User = $User.castUserDoc(doc);