0

我有以下两个架构:

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

我在任何地方都找不到的是猫鼬如何确定从哪里获取“消息”填充 - “发件人”字段或“收件人”字段......

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

10 倍。

4

1 回答 1

3

我不知道我是否理解正确,但无论如何,猫鼬在任何时候都在填充什么是非常清楚的。

如果你运行Message.find().populate('sender recipient').exec(..),你会得到每个文档,senderrecipient成为它们各自的 MongoDB 文档。

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

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

这将返回userId发件人所在的所有消息。但是,消息数组作为回报没有填充,这意味着您将只有接收者 ID,但没有它的名称,在大多数用例中,您可能希望在这些情况下拥有它。因此,现在您必须再次按这些 id 填充或选择用户。

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

你的设计看起来像你有关系数据库的背景,不存储冗余信息并坚持数据库规范化规则。但 MongoDB 与关系无关。尽管这对您来说可能听起来很奇怪,但请考虑将所需的用户名直接存储在消息对象中。

您可能会认为一旦用户更改其名称,这种方式的信息就会过时,您是对的。但是,与他写和接收消息的次数相比,用户真正改名的次数有多少。因此,当用户更改他的名字时,每隔一段时间更新一次消息模型,而不是一遍又一遍地填充。

于 2014-11-22T09:12:14.913 回答