我是 mongoose 的新手,老实说还有大量的阅读工作要做,但我正在研究一个小型宠物项目,该项目可以读取和写入 mongo db。在这种情况下,我想使用猫鼬来确保一致的文档模型。
问题在于独立地确保插入和更新操作中的默认值。特别是,我分别指的是 addedOn 和 updatedOn 字段。我要求持久性的方法是 findOneAndUpdate,它现在支持中间件挂钩(从 4.0 开始)。
我能够使基本挂钩工作(每次都应用 updatedOn 日期),但无法弄清楚如何为默认 addOn 的插入案例添加支持(猫鼬方式)。这是简单的模式和钩子(用于处理插入和更新):
const TestSchema = new Schema({
id : ObjectId,
name : String,
addedOn : { type: Date, default: Date.now },
updatedOn : { type: Date, default: Date.now }
});
TestSchema.pre('findOneAndUpdate', function(next) {
console.log('hook::findOneAndUpdate')
// update defaults
this.update({addedOn: {$exists:true}},{
$set: {
updatedOn: new Date()
}
})
// insert defaults
this.update({addedOn: {$exists:false}},{
$set: {
addedOn: new Date(),
updatedOn: new Date()
}
})
next();
});
毫不奇怪(因为它确实是赃物)它不起作用。每次运行应用程序时都会插入一行。如果向更新方法添加条件会覆盖默认匹配(尚未挖掘源),则会出现这种情况。
这是我对单独更新案例的初始片段,它找到了行并正确更新,但如上所述无法处理 addedOn(它会每次都更新它)
TestSchema.pre('findOneAndUpdate', function(next) {
console.log('hook::findOneAndUpdate')
this.update({},{
$set: {
updatedOn: new Date()
}
})
next();
});
驱动所有这一切的是这个片段(使代码尽可能接近我正在开发的应用程序的民间故事实现的习惯用法)
mongoose.connect('mongodb://localhost/network');
const model = mongoose.model('TestSchema', TestSchema)
const schema = TestSchema
const collection = model
const findOneAndUpdate = (collection) => {
return (criteria, record) => {
return new Task((reject, resolve) => {
const callback = (error, data) => {
if (error) {
reject(error)
}
else {
resolve(data)
}
}
collection.findOneAndUpdate(criteria, record, {upsert: true}, callback)
})
}
}
const upsert = findOneAndUpdate(collection)
upsert({name: "me"}, {name: "me"}).fork(console.log, console.error)
我可以修改我的 findOneAndUpdate 函数来添加 addedOn - 但我真的很想正确使用猫鼬钩子。