MongooseJS使用多个目标字段填充

时间:2014-11-22 08:41:32

标签: node.js mongodb mongoose mongoose-populate

我有以下两种模式:

var MessageModel = mongoose.model("message",
    new Schema({
        sender:{type:ObjectId,ref:"user"},
        recipient:{type:ObjectId,ref:"user"},
        title: String
    })
);

var UserModel = mongoose.model("user", 
    new Schema({
        username: String,
        name: String,
        fname: String,
        messages:[{type:ObjectId,ref:"message"}]
    })
);

我无法在任何地方找到的是mongoose如何确定从“发件人”字段或“收件人”字段填充“邮件”的位置......

是一个吗?都?这可以配置吗? 即我可以创建单独的'incomingMessage'和'outgoingMessages'字段以及如何?

10倍。

1 个答案:

答案 0 :(得分:3)

我不知道我是否正确理解这一点,但它在任何时候都是非常清楚Mongoose正在填充的内容。

如果您运行Message.find().populate('sender recipient').exec(..),则会将senderrecipient的每个文档作为其各自的MongoDB文档。

如果运行User.find().populate('messages').exec(..),则会获得与ObjectId匹配的每条消息的数组。根据您的设计,我们无法知道用户是发件人还是收件人。但如果您事先知道用户身份,我们可以过滤它:

User.find().populate({
    path: 'messages',
    match: { sender: userId }
}).exec(..)

这将返回userId是发件人的所有邮件。然而,messages数组不会被填充,这意味着您将只拥有接收者ID,而不是其名称,在这种情况下您可能希望拥有的大多数用例。所以现在你必须再次按这些ID填充或选择用户。

但要记住这一点,如果你发现自己一遍又一遍地填充,你必须重新考虑你的设计,否则MongoDB可能不是正确的解决方案。

您的设计看起来像是有关系数据库的背景,不存储冗余信息并坚持数据库规范化规则。但MongoDB并不是关系。即使这听起来很奇怪,但想想在消息对象中存储所需的用户名。

您可能会认为这样一旦用户更改其名称信息就会过时,并且您是正确的。但是,与他写入和接收消息的次数相比,用户真正改变了他的名字多少次。因此,在用户更改名称时,每次更新消息模型,而不是一遍又一遍地填充。