这是我正在处理的架构。
var testSchema = mongoose.Schema({
userCreated : {
type : mongoose.Schema.Types.ObjectId,
ref : "User"
},
points : {type: Number, default: 0},
numVotes : {type: Number, default: 0},
createdAt : Date,
updatedAt : Date,
}, { timestamps : true });
现在,我正在尝试编写一个函数,该函数将增加此文档(points
和numVotes
上的两个字段,以及用户模式上存在的其他points
字段
这是我的尝试。
testSchema.statics.incrementTest = function(id, ...) {
this.findByIdAndUpdate(id, {$inc : {
points : 5,
numVotes : 1,
'userCreated.points' : 5
}}).exec();
}
现在,我写的这段代码不起作用。但是,当我注释掉'userCreated.points' : 5
行时,其他两个字段会按预期增加。我的问题是,使用mongoose同时更新文档中的字段和子文档上的字段的最佳方法是什么?
答案 0 :(得分:1)
此处的数据包含在不同的集合中,因此没有一个update语句能够同时增加两个计数器。
为了获得一致的视图,您需要"链"您的更新语句并使用每个语句的返回结果来构建响应。
根据您的需要,您可以使用Promise
:
testSchema.statics.incrementTest = function(id) {
var self = this;
return new Promise(function(resolve,reject) {
self.findByIdAndUpdate(
id,
{
"$inc": {
"points": 5,
"numVotes": 1
}
},
{ "new": true }
).then(function(test) {
var userModel = test.schema.path("userCreated").options.ref;
mongoose.model(userModel).findByIdAndUpdate(
test.userCreated,
{ "$inc": { "points": 5 } },
{ "new": true }
).then(function(user) {
test.userCreated = user;
resolve(test);
})
}).catch(reject)
})
};
然后您可以在模型上调用:
Test.incrementTest("56fe279d363ce91765d9e39e").then(function(test) {
console.log(JSON.stringify(test,undefined,2));
}).catch(function(err) {
throw err;
})
如果您更适合,可以使用async.waterfall
库中的async
:
testSchema.statics.incrementTest = function(id,callback) {
var self = this;
async.waterfall(
[
function(callback) {
self.findByIdAndUpdate(
id,
{
"$inc": {
"points": 5,
"numVotes": 1
}
},
{ "new": true },
callback
)
},
function(err,test) {
if (err) callback(err);
var userModel = test.schema.path("userCreated").options.ref;
mongoose.model(userModel).findByIdAndUpdate(
test.userCreated,
{ "$inc": { "points": 5 } },
{ "new": true },
function(err,user) {
if ( typeof(user) !== "undefined" )
test.userCreated = user;
callback(err,test);
}
);
}
],
callback
);
};
具有类似用法:
Test.incrementTest("56fe279d363ce91765d9e39e",function(err,test) {
if (err) throw err;
console.log(JSON.stringify(test,undefined,2));
})
两者都应该给你一个结果,显示两个集合中两个对象的增量数据:
{ points: 5,
numVotes: 1,
__v: 0,
userCreated: { points: 5, __v: 0, _id: 56ff1aa6dba6d13e798fc894 },
createdAt: Sat Apr 02 2016 12:04:38 GMT+1100 (AEDT),
updatedAt: Sat Apr 02 2016 12:04:38 GMT+1100 (AEDT),
_id: 56fe279d363ce91765d9e39e }