我想填充子文档的字段,该子文档是公共架构的区别元素( Notificationable 被区分为 MessageFriendRequest ) .

这个问题与这个问题非常相似:mongoosejs: populating an array of objectId's from different schemas,两年前没有解决 . 既然猫鼬进化了,也有鉴别者,我再问这个问题 .

到目前为止我尝试了什么:

Notification.find({_id: 'whatever'})
    .populate({
        path: 'payload',
        match: {type: 'Message'},
        populate: ['author', 'messageThread']
    })
    .populate({
        path: 'payload',
        match: {type: 'FriendRequest'},
        populate: ['to', 'from']
    })
    .exec();

这不起作用,因为路径是相同的 . 所以我尝试过:

Notification.find({_id: 'whatever'})
    .populate({
        path: 'payload',
        populate: [
            {
                path: 'messageThread',
                match: {type: 'Message'},
            },
            {
                path: 'author',
                match: {type: 'Message'},
            },
            {
                path: 'from',
                match: {type: 'FriendRequest'},
            },
            {
                path: 'to',
                match: {type: 'FriendRequest'},
            },

        ]
    })
    .exec();

这也不起作用,可能是因为匹配在子文档中执行,因此没有字段 type .

这有什么解决方案吗?


这是我的(主要)模型,我没有提供User或MessageThread .

The main document:

const NotificationSchema = new Schema({
    title: String,
    payload: {
        type: Schema.Types.ObjectId,
        ref: 'Notificationable'
    });
mongoose.model('Notification', NotificationSchema);

The payload Parent schema

let NotificationableSchema = new Schema(
    {},
    {discriminatorKey: 'type', timestamps: true}
);
mongoose.model('Notificationable', NotificationableSchema);

这两个有区别的可能性:

let Message = new Schema({
    author: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    messageThread: {
        type: Schema.Types.ObjectId, 
        ref: 'MessageThread'
    }
}
Notificationable.discriminator('Message', Message);

和:

let FriendRequest = new Schema({
    from: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    to: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    }
}
Notificationable.discriminator('FriendRequest', FriendRequest);