Object.assign() 在分配 mongoose 文档时创建奇怪的属性
Object.assign() creates wierd properties when assigns mongoose doc
MessageThread.findById(req.body._id)
.populate({ path: "messages" })
.exec((err, foundMessageThread) => {
var filtered = foundMessageThread.messages.map(message=>{
return Object.assign({}, message, {isRead: true});
})
console.log("filtered", filtered);
});
console.log 显示:
{ '$__':
InternalCache {
strictMode: true,
selected: {},
shardval: undefined,
saveError: undefined,
validationError: undefined,
adhocPaths: undefined,
removing: undefined,
inserting: undefined,
version: undefined,
getters: {},
_id: 5a4c7f2d8b49fc260c396f55,
populate: undefined,
populated: undefined,
wasPopulated: true,
scope: undefined,
activePaths: [Object],
pathsToScopes: {},
ownerDocument: undefined,
fullPath: undefined,
emitter: [Object],
'$options': true },
isNew: false,
errors: undefined,
_doc:
{ sentAt: 2018-01-03T06:58:53.188Z,
isRead: false,
_id: 5a4c7f2d8b49fc260c396f55,
sender: 5a4b77767251b44cd870219f,
reciever: 5a4b780a7251b44cd87021a1,
text: 'qwe',
__v: 0 },
'$init': true,
isRead: true },
......
它重复了很多次。
我想它 (InternalCache { strictMode: true...) 与取自 foundMessageThread 的 message 有关。它在分配时揭示了它的元数据(在我的术语中)。因为:
MessageThread.findById(req.body._id)
.populate({ path: "messages" })
.exec((err, foundMessageThread) => {
var filtered = foundMessageThread.messages.map(message=>{
console.log("message", message)
return Object.assign({}, message, {isRead: true});
})
console.log("filtered", filtered);
});
console.log 显示
{ sentAt: 2018-01-03T06:58:53.188Z,
isRead: false,
_id: 5a4c7f2d8b49fc260c396f55,
sender: 5a4b77767251b44cd870219f,
reciever: 5a4b780a7251b44cd87021a1,
text: 'qwe',
__v: 0 },
....
我的问题:
- 这是正常行为吗?
- 如果是怎么解决?因为 "metadata" 阻止对象被赋值。
P.S。我试过:
MessageThread.findById(req.body._id)
.populate({ path: "messages" })
.exec((err, foundMessageThread) => {
var filtered = foundMessageThread.messages.map(message=>{
return **Object.assign({}, message._doc, {isRead: true})**;
})
console.log("filtered", filtered);
});
这是猫鼬的正常行为。 mongoose 返回的对象包装了实际数据,以便向其添加行为(方法)。
您可以使用 toObject
方法获取实际数据对象,例如 message.toObject()
.
然而,有像 __v
这样的属性被 mongoose 用于管理目的。如果你不想要它们,你可以像这样修改toObject
方法
messageSchema.set('toObject', {
versionKey: false,
transform: (doc, ret) => {
delete ret.__v;
return ret;
},
});
如果要对这些对象进行赋值或从这些对象赋值,似乎应该引用猫鼬对象的 _doc
属性。事实上,我无法像 mongoDoc.newProp = propValue;
这样以正常方式设置其他属性。它没有改变原始对象。
对于赋值,而不是:
Object.assign(mongoDoc, {a: 1, b: 2});
你想要:
Object.assign(mongoDoc._doc, {a: 1, b: 2});
或者,如果您要将 mongoDoc 属性分配给另一个对象,您需要
Object.assign({a: 1, b: 2}, mongoDoc._doc);
您还可以对 mongoose 请求使用 .lean()
方法。这样可以减少繁琐的响应并轻松处理它:
try {
const assets = await myModel.Assets
.find({ isActive: true }, { __v: 0, _id: 0 })
.lean()
.exec()
// do something
}
catch(error) {
throw error
}
MessageThread.findById(req.body._id)
.populate({ path: "messages" })
.exec((err, foundMessageThread) => {
var filtered = foundMessageThread.messages.map(message=>{
return Object.assign({}, message, {isRead: true});
})
console.log("filtered", filtered);
});
console.log 显示:
{ '$__':
InternalCache {
strictMode: true,
selected: {},
shardval: undefined,
saveError: undefined,
validationError: undefined,
adhocPaths: undefined,
removing: undefined,
inserting: undefined,
version: undefined,
getters: {},
_id: 5a4c7f2d8b49fc260c396f55,
populate: undefined,
populated: undefined,
wasPopulated: true,
scope: undefined,
activePaths: [Object],
pathsToScopes: {},
ownerDocument: undefined,
fullPath: undefined,
emitter: [Object],
'$options': true },
isNew: false,
errors: undefined,
_doc:
{ sentAt: 2018-01-03T06:58:53.188Z,
isRead: false,
_id: 5a4c7f2d8b49fc260c396f55,
sender: 5a4b77767251b44cd870219f,
reciever: 5a4b780a7251b44cd87021a1,
text: 'qwe',
__v: 0 },
'$init': true,
isRead: true },
......
它重复了很多次。 我想它 (InternalCache { strictMode: true...) 与取自 foundMessageThread 的 message 有关。它在分配时揭示了它的元数据(在我的术语中)。因为:
MessageThread.findById(req.body._id)
.populate({ path: "messages" })
.exec((err, foundMessageThread) => {
var filtered = foundMessageThread.messages.map(message=>{
console.log("message", message)
return Object.assign({}, message, {isRead: true});
})
console.log("filtered", filtered);
});
console.log 显示
{ sentAt: 2018-01-03T06:58:53.188Z,
isRead: false,
_id: 5a4c7f2d8b49fc260c396f55,
sender: 5a4b77767251b44cd870219f,
reciever: 5a4b780a7251b44cd87021a1,
text: 'qwe',
__v: 0 },
....
我的问题:
- 这是正常行为吗?
- 如果是怎么解决?因为 "metadata" 阻止对象被赋值。
P.S。我试过:
MessageThread.findById(req.body._id)
.populate({ path: "messages" })
.exec((err, foundMessageThread) => {
var filtered = foundMessageThread.messages.map(message=>{
return **Object.assign({}, message._doc, {isRead: true})**;
})
console.log("filtered", filtered);
});
这是猫鼬的正常行为。 mongoose 返回的对象包装了实际数据,以便向其添加行为(方法)。
您可以使用 toObject
方法获取实际数据对象,例如 message.toObject()
.
然而,有像 __v
这样的属性被 mongoose 用于管理目的。如果你不想要它们,你可以像这样修改toObject
方法
messageSchema.set('toObject', {
versionKey: false,
transform: (doc, ret) => {
delete ret.__v;
return ret;
},
});
如果要对这些对象进行赋值或从这些对象赋值,似乎应该引用猫鼬对象的 _doc
属性。事实上,我无法像 mongoDoc.newProp = propValue;
这样以正常方式设置其他属性。它没有改变原始对象。
对于赋值,而不是:
Object.assign(mongoDoc, {a: 1, b: 2});
你想要:
Object.assign(mongoDoc._doc, {a: 1, b: 2});
或者,如果您要将 mongoDoc 属性分配给另一个对象,您需要
Object.assign({a: 1, b: 2}, mongoDoc._doc);
您还可以对 mongoose 请求使用 .lean()
方法。这样可以减少繁琐的响应并轻松处理它:
try {
const assets = await myModel.Assets
.find({ isActive: true }, { __v: 0, _id: 0 })
.lean()
.exec()
// do something
}
catch(error) {
throw error
}