我正在尝试避免数据库回调查询。
假设您有两个看起来像这样的架构:
1st)用户架构
username : {type: String, unique: true},
age : {type: Number}
2nd)活动架构
owner: [{type: Schema.Types.ObjectId, ref: 'User'}],
city: {type: String},
date: {type: Date}
到目前为止,一切都很好。
现在,假设您有一条到达的路线/user/:id
,您期望得到username
和age
,但是如果我也想在那条路线上返回最新活动,该怎么办?
编辑:请注意,这latest activity
不是数据库中的值。它像activity.find({owner: ObjectId(id)}).sort({date: -1}).limit(1)
现在做什么:
User.findOne({username:req.params.username}).lean().exec(function(err,userDoc)
{
if(err) return errHandler(err);
Activity.findOne({owner:userDoc.username}).sort({date:-1}).exec(function(err,EventDoc){
if(err) return errHandler(err);
userDoc.latest_activity = EventDoc._id;
res.json(userDoc);
res.end();
})
})
上面的代码段的问题在于难以维护,如果我们想向此API功能添加更多功能该怎么办?除非我们实现Q,否则我们将以查询的地狱结束。
我们尝试查看Virtual,但是问题在于您不能真正在猫鼬Virtual内部查询,因为它返回了竞争条件,而且您极有可能无法按时获得该文档。
我们还尝试查看填充,但是由于关于填充的文档非常糟糕,我们无法做到这一点。
问题: 是否仍要使它更具模块化?
有什么办法可以避免地狱的数据库查询回调?
例如,这种事情可能吗?
User.findOne({username:req.params.username}).lean().populate(
{path:'Event',sort:{Date:-1}, limit(1)}
).exec(function(req,res))...
谢谢!
受到@BrianShambien答案的启发,您可以保存帖子,但不仅可以将存储_id
在用户上,还可以存储仅上一个活动的子文档。然后,当您抓住该用户时,该用户就在那里拥有最后一个活动。
用户模型
username : {type: String, unique: true},
age : {type: Number},
last_activity: ActivitySchema
然后,在您的 ActivitySchema
ActivitySchema.post('save', function(doc) {
UserSchema.findOne({username: doc.owner}).exec(function(err, user){
if (err) errHandler(err);
user.last_activity = doc;
user.save(function(err) {
if (err) errHandler(err);
});
});
});
**********更新************
如果用户不是所有者,而是活动的参与者,这将包括对用户的更新。
ActivitySchema.post('save', function(doc) {
findAndUpdateUser(doc.owner, doc);
if (doc.participants) {
for (var i in doc.participants) {
findAndUpdateUser(doc.participants[i], doc);
}
}
});
var findAndUpdateUser = function (username, doc) {
UserSchema.findOne({username: username}).exec(function (err, user) {
if (err) errHandler(err);
user.last_activity = doc;
user.save(function (err) {
if (err) errHandler(err);
});
});
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句