MongooseJS 使用多个目标字段填充

Posted

技术标签:

【中文标题】MongooseJS 使用多个目标字段填充【英文标题】:MongooseJS populate using multiple target fields 【发布时间】:2015-01-20 10:31:11 【问题描述】:

我有以下两个架构:

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】:

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

如果您运行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 与关系无关。尽管您可能听起来很奇怪,但请考虑将所需的用户名直接存储在消息对象中。

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

【讨论】:

关于 Mongo 用例的惊人解释。 10 倍。这个问题更多是出于好奇。我同意你所说的大部分内容。我只是想知道如何创建一个填充字段:“incomingMessages”和“outgoingMessages”,其中传入将仅填充以用户为收件人的消息,而传出则以用户为消息发送者。我仍然需要检查它,但猜想你的例子可能有效......

以上是关于MongooseJS 使用多个目标字段填充的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 mongoosejs 填充

MongooseJS 在填充后返回空数组

是否可以在 mongoosejs 模式中填充自引用?

填充嵌套引用的更好方法 mongoosejs

Mongoosejs:findById 比 findOne 快吗?

mongoosejs 定义复杂模型