我有以下两种模式:
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倍。
答案 0 :(得分:3)
我不知道我是否正确理解这一点,但它在任何时候都是非常清楚Mongoose正在填充的内容。
如果您运行Message.find().populate('sender recipient').exec(..)
,则会将sender
和recipient
的每个文档作为其各自的MongoDB文档。
如果运行User.find().populate('messages').exec(..)
,则会获得与ObjectId匹配的每条消息的数组。根据您的设计,我们无法知道用户是发件人还是收件人。但如果您事先知道用户身份,我们可以过滤它:
User.find().populate({
path: 'messages',
match: { sender: userId }
}).exec(..)
这将返回userId
是发件人的所有邮件。然而,messages数组不会被填充,这意味着您将只拥有接收者ID,而不是其名称,在这种情况下您可能希望拥有的大多数用例。所以现在你必须再次按这些ID填充或选择用户。
但要记住这一点,如果你发现自己一遍又一遍地填充,你必须重新考虑你的设计,否则MongoDB可能不是正确的解决方案。
您的设计看起来像是有关系数据库的背景,不存储冗余信息并坚持数据库规范化规则。但MongoDB并不是关系。即使这听起来很奇怪,但想想在消息对象中存储所需的用户名。
您可能会认为这样一旦用户更改其名称信息就会过时,并且您是正确的。但是,与他写入和接收消息的次数相比,用户真正改变了他的名字多少次。因此,在用户更改名称时,每次更新消息模型,而不是一遍又一遍地填充。