mongoose 父文档中数组内部的子文档的动态ObjectID ref

7gs2gvoe  于 9个月前  发布在  Go
关注(0)|答案(1)|浏览(120)

我尝试为存储在子文档的属性中的对象ID创建动态引用。该属性可以引用多个模型(甚至是在不同mongoose数据库示例中注册的模型),因此我直接使用模型示例而不是模型名称。

const subSchema = new Schema({
    category: String,
    ref: {
        type: Schema.Types.ObjectId,
        ref: function() {
            return this.category === 'catA' ? CategoryAModel : CategoryBModel // imports model instances
        }
    }
})

const parentSchema = new Schema({
    name: String,
    children: [subSchema]
})

const ParentModel = db.model('Parent', parentSchema)

字符串
正如你所看到的,ref属性是来自CategoryAModelCategoryBModel的文档的Object ID。我开始为这个模型创建文档,如下所示:

const data = {
    name: 'Test Data',
    children: [
        {
            category: 'catA',
            ref: '658e9f1901f3da2c14920401' // <- existing document from CategoryAModel
        },
        {
            category: 'catB',
            ref: '654995e0c89d1c19c84e77b7' // <- existing document from CategoryBModel
        }
    ]
}


但是当我尝试populate时,category: 'catA'ref变为null。我在ref的ref函数中记录了this上下文,发现this引用了正在处理的文档(与上面的数据相同的形状),并且this.category是未定义的,因为它实际上在children数组中。本质上,使ref始终成为CategoryBModel
既然它是一个数组,我该怎么做一个动态引用呢?有没有办法访问被引用的subSchema的索引呢?

3yhwsihp

3yhwsihp1#

您应该使用refPath。Mongoose设计了populate方法,将refPath选项用于动态模型,并将满足您的需求。
像这样使用它:

const subSchema = new Schema({
    category: String,
    ref: {
        type: Schema.Types.ObjectId,
        refPath: 'children.classifier', //< refPath should point to classifier
    },
    classifier: {
       type: String,
       enum: ['CategoryAModel', 'CategoryBModel'] //< The name of your models
    }
})

字符串
现在当你保存你的Parent文档时,children对象应该有你想要填充的模型存储在那个classifier字符串中。你的数据看起来像这样:

const data = {
   name: 'Test Data',
   children: [
      {
         category: 'catA',
         ref: ObjectId("658e9f1901f3da2c14920401"), // <- existing document from CategoryAModel
         classifier: 'CategoryAModel'
      },
      {
         category: 'catB',
         ref: ObjectId("654995e0c89d1c19c84e77b7"), // <- existing document from CategoryBModel
         classifier: 'CategoryBModel'
      }
   ]
}


现在你可以像这样填充:

const parents = await ParentModel.find({}).populate("children.ref");

相关问题