Mongoose - REST API - 带有查询的Schema到不同的模型

时间:2014-12-14 22:54:29

标签: node.js rest express mongoose

我试图避免数据库回调查询。

假设您有两个类似的模式:

  

1st) 用户架构

 username : {type: String, unique: true},
 age : {type: Number}
  

2) 活动架构

 owner: [{type: Schema.Types.ObjectId, ref: 'User'}],
 city: {type: String},
 date: {type: Date}

到目前为止一切顺利。

现在假设你有一条前往/user/:id的路线,你期望的是获得usernameage,但是如果我还希望返回该路线怎么办? 最新活动

编辑:请注意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,否则我们最终会回调查询。

  

我们试图看看虚拟,但问题在于你无法做到   真的在mongoose Virtual里面查询,因为它返回一个   竞争条件,你很可能没准时得到那份文件。

我们也尝试查看populate,但我们无法做到这一点,因为有关populate的文档非常差。

问题: 无论如何使这更加模块化?

有没有办法避免地狱的数据库查询回调?

例如,这种事情可能吗?

    User.findOne({username:req.params.username}).lean().populate(
{path:'Event',sort:{Date:-1}, limit(1)}
).exec(function(req,res))...

谢谢!

2 个答案:

答案 0 :(得分:4)

在这种情况下,处理它的最佳方法是在Activity架构中添加一个帖子保存挂钩,以便将最新的_id存储在latest_activity的{​​{1}}路径中{1}}架构。这样,您无需进行额外查询即可始终访问ID。

User

答案 1 :(得分:4)

受@ 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);
        });
    });
});

********** UPDATE ************

如果用户不是所有者,而是该活动的参与者,则包括对用户的更新。

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);
        });
    });
});