更新参考以及其他值 Mongoose [英] Updating Reference Along With Other Values Mongoose
问题描述
这是我正在处理的架构.
Here is a schema that I am working on.
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
code> 存在于用户架构中的字段.
Now, I am trying to write a function that will increment two fields on this document (points
and numVotes
, as well as an additional points
field that exists on the user schema.
这是我的尝试.
testSchema.statics.incrementTest = function(id, ...) {
this.findByIdAndUpdate(id, {$inc : {
points : 5,
numVotes : 1,
'userCreated.points' : 5
}}).exec();
}
现在,我编写的这段代码不起作用.但是,当我注释掉 'userCreated.points' : 5
行时,其他两个字段会按预期增加.我的问题是,使用猫鼬同时更新文档上的字段和子文档上的字段的最佳方法是什么?
Now, this code that I have written does not work. However, when I comment out the 'userCreated.points' : 5
line, the other two fields do increment as expected. My question is, what is the best way using mongoose to update the fields on a document and the fields on a subdocument at the same time?
推荐答案
这里的数据包含在不同的集合中,因此没有一个更新语句能够同时增加两个集合中的计数器.
The data here is contained in different collections, so no single update statement is able to increment counters in both at the same time.
为了获得一致的视图,您需要链接"您的更新语句并使用每个语句的返回结果来构建响应.
In order to get a consistent view you are going to need to "chain" your update statements and use the return results of each to build the response.
根据您的需要,您可以使用 Promise
与此:
Depending on your needs you can either use a Promise
with this:
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)
})
};
然后您可以在模型上调用它:
Which you can then invoke on your model:
Test.incrementTest("56fe279d363ce91765d9e39e").then(function(test) {
console.log(JSON.stringify(test,undefined,2));
}).catch(function(err) {
throw err;
})
或者你可以使用 async
库中的 async.waterfall
如果它更适合你:
Or you can use async.waterfall
from the async
library if that suits you better:
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));
})
两者都应该给你一个结果,显示两个集合的两个对象中的增量数据:
Both should be giving you a result back that shows the incremented data in both objects for both collections:
{ 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 }
这篇关于更新参考以及其他值 Mongoose的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!