猫鼬:填充人口稠密的土地

Fra*_*esc 18 populate mongoose mongodb node.js

我正在使用MongoDB作为我的应用程序的日志管理器,然后同步移动客户端.我在NodeJS中设置了这个模型:

var UserArticle = new Schema({
    date: { type: Number, default: Math.round((new Date()).getTime() / 1000) }, //Timestamp!
    user: [{type: Schema.ObjectId, ref: "User"}],
    article: [{type: Schema.ObjectId, ref: "Article"}],
    place: Number,    
    read: Number,     
    starred: Number,   
    source: String
});
mongoose.model("UserArticle",UserArticle);

var Log = new Schema({
    user: [{type: Schema.ObjectId, ref: "User"}],
    action: Number, // O => Insert, 1 => Update, 2 => Delete
    uarticle: [{type: Schema.ObjectId, ref: "UserArticle"}],
    timestamp: { type: Number, default: Math.round((new Date()).getTime() / 1000) }
});
mongoose.model("Log",Log);
Run Code Online (Sandbox Code Playgroud)

当我想要检索日志时,我使用以下代码:


var log = mongoose.model('Log');
log
.where("user", req.session.user)
.desc("timestamp")
.populate("uarticle")
.populate("uarticle.article")
.run(function (err, articles) {
if (err) {
    console.log(err);
        res.send(500);
    return;
}
res.json(articles);
Run Code Online (Sandbox Code Playgroud)

如您所见,我希望mongoose从Log集合中填充"uarticle"字段,然后,我想填充UserArticle("uarticle")的"article"字段.

但是,使用此代码,Mongoose仅使用UserArticle模型填充"uarticle",而不是uarticle中的article字段.

是否可以使用Mongoose和populate()来完成它,或者我应该做些什么呢?

谢谢,

ale*_*lex 15

根据我在文档中检查的内容以及我从您那里听到的内容,这无法实现,但您可以在回调函数中自己填充"uarticle.article"文档.

但是我想指出另一个我认为更重要的方面.您在集合A中有文档,其中引用了集合B,而在集合B的文档中,您对集合C中的文档有另一个引用.

你要么做错了(我指的是数据库结构),要么你应该在这里使用像MySQL这样的关系数据库.MongoDB的强大之处在于您可以在文档中嵌入更多信息,因此必须进行较少的查询(将您的数据放在一个集合中).虽然引用某些东西是可以的,但是有一个引用然后另一个引用似乎并不像你在这里充分利用了MongoDB.

也许您想分享您的情况和数据库结构,以便我们可以帮助您更多.


Buu*_*yen 5

您可以使用mongoose-deep-populate插件执行此操作.用法:

User.find({}, function (err, users) {
   User.deepPopulate(users, 'uarticle.article', function (err, users) {
      // now each user document includes uarticle and each uarticle includes article
   })
})
Run Code Online (Sandbox Code Playgroud)

免责声明:我是该插件的作者.


Nav*_*mar 5

我遇到了同样的问题,但经过几个小时的努力我找到了解决方案。它可以不使用任何外部插件:)

    applicantListToExport: function (query, callback) {
      this
       .find(query).select({'advtId': 0})
       .populate({
          path: 'influId',
          model: 'influencer',
          select: { '_id': 1,'user':1},
          populate: {
            path: 'userid',
            model: 'User'
          }
       })
     .populate('campaignId',{'campaignTitle':1})
     .exec(callback);
    }
Run Code Online (Sandbox Code Playgroud)