我正在尝试更新预挂钩上的计数。问题是,由于某些未知原因,findOneAndUpdate
挂钩无法访问该文档,据我所知。
我想这样做:
source.pre('findOneAndUpdate', function (next) {
console.log('------------->>>>>> findOneAndUpdate: ');
this.objects = this.objects || [];
this.people = this.people || [];
this.events = this.events || [];
this.objectCount = this.objects.length;
this.peopleCount = this.people.length;
this.eventCount = this.events.length;
next();
});
但由于某些原因,钩子中的this
不是文档,它的Query对象似乎没用。
我错过了什么? 如何使用预挂钩更新findOneAndUpdate上的计数?
答案 0 :(得分:12)
你可以做那样的smthng - >
source.pre('findOneAndUpdate', function (next) {
console.log('------------->>>>>> findOneAndUpdate: ');
this._update.$set.objects = [];
this._update.$set.people = [];
this._update.$set.events = [];
next();
});
注意_update。$ set因为在上下文中“this”将是一个查询。所以你可以轻松添加你想要的任何东西!
答案 1 :(得分:7)
查询中间件与文档中间件的区别在于微妙但重要的方式:在文档中间件中,
this
指的是正在更新的文档。在查询中间件中,mongoose不一定要引用正在更新的文档,因此this
指的是查询对象而不是正在更新的文档。
更新操作通常会更新仅存在于数据库中的文档(它告诉MongoDB服务器:"查找文档X并将属性X设置为值Z" ),因此Mongoose无法使用完整的文档,因此您无法更新计数(至少需要访问您想要确定其长度的数组)。
顺便说一下:为什么在架构中需要单独的*Count
属性?如果要查询匹配特定大小的数组,可以直接在数组上使用$size
运算符。
如果确实需要计数属性,那么对于每次更新,您需要跟踪对每个阵列所做的更改次数(根据添加/删除的项目数)并使用{{3 }}运算符来调整计数。
答案 2 :(得分:0)
当我使用updateOne方法时也遇到了类似的问题,并且还打算使用updateOne预挂钩在保存到数据库之前进行间歇更新。找不到工作的方法。我最终使用了findOneAndUpdate预钩,并在其中执行了updateOne。
schema.pre('findOneAndUpdate', async function(next){
const schema = this;
const { newUpdate } = schema.getUpdate();
const queryConditions = schema._condition
if(newUpdate){
//some mutation magic
await schema.updateOne(queryConditions, {newUpdate:"modified data"});
next()
}
next()
})
答案 3 :(得分:0)
另一种解决方案是使用中间件上的官方MongoDB文档。他们解释了为什么“ this”不引用文档本身。您可以尝试使用这种方式进行尝试:
source.pre('findOneAndUpdate', async function(next) {
const docToUpdate = await this.model.findOne(this.getFilter());
//modify the appropriate objects
docToUpdate.save(function(err) {
if(!err) {
console.log("Document Updated");
}
});
console.log(docToUpdate);
// The document that `findOneAndUpdate()` will modify
next();
});
答案 4 :(得分:0)
这对我有用
SCHEMA.pre('findOneAndUpdate', function(next){
this._update.yourNestedElement
next();
});