如果第一个模型为空,如何填充第二个模型

Posted

技术标签:

【中文标题】如果第一个模型为空,如何填充第二个模型【英文标题】:How to populate with a second model if first one is empty 【发布时间】:2017-05-23 10:02:39 【问题描述】:

我有三个模型,

模型A、模型B和模型C

ModelC的数据在这里


 "_id" : ObjectId("586e1661d9903c6027a3b47c"),
 "RefModel" : "modelA",
 "RefId" : ObjectId("57f37f18517f72bc09ee7632")
,

 "_id" : ObjectId("586e1661d9903c6027a3b47c"),
 "RefModel" : "modelB",
 "RefId" : ObjectId("57f37f18517f72bc09ee7698")
,

如何为 ModelC 编写填充查询,以使用 RefId 进行填充。

它应该填充 RefModel 引用的 modelA 或 modelB。

我试过了

 ModelC.find()
       .populate( path: 'RefId', model: 'modelA' )
       .populate( path: 'RefId', model: 'modelB' )

但只取最后一个模型。

modelC 架构。

new mongoose.Schema(
  RefModel: String,
  RefId: type: Schema.ObjectId);

我可以使用聚合来完成,但更喜欢填充。

【问题讨论】:

请添加模型的架构代码 @styopdev 添加请检查。 看我的回答,你可以从回调内部填充结果对象 【参考方案1】:

你的数据库和架构中的字段名称非常混乱,让我用更清晰的例子来解释一下。

假设您有 3 个模型:用户、文章和评论。文章和评论仅属于单个用户。用户可以有多个 cmets 和文章(如您在示例中所示)。

    (更高效和推荐的方式)。将 cmets 和文章 ids 存储在 User 模型中,例如:

comments: [ id: '..', ref: Comment ], articles: [ id: '..', ref: Article ]

并填充您的文档:

User.find()
    .populate('comments')
    .populate('articles');
    将用户 ID 存储在评论和文章模型中,例如

user: id: '...', ref: User

并使用mongoose-reverse-populate 模块进行填充,例如用于 cmets 模型:

var reversePopulate = require('mongoose-reverse-populate');

User.find().exec(function(err, users) 

    var opts = 
        modelArray: users,
        storeWhere: "comments",
        arrayPop: true,
        mongooseModel: Comments,
        idField: "user"
    

    reversePopulate(opts, function(err, popUsers) 
        // populated users will be populated with comments under .comments property
    );
);

此外,您不需要将 RefModel 保留在数据库中,仅保留在模式中。

【讨论】:

我无法更新数据库/模型。需要实现退出的功能。【参考方案2】:

在这里,您可以尝试将其填充到 find 本身的回调中。

试试这个:

ModelC.find().exec(function(err,modelC)
    //find returns an array of Object, you will have to populate each Object individually.
    var modelCObjects =[];
    modelC.forEach(function(tempModelC)
        //populate via the Model
        ModelC.populate(tempModelC,path : tempModelC.refId , model :tempModelC.refModel,function(err2,newModelC)
            //handle newModelC however you want
            //Push it into array of modelC Objects
            modelCObjects.push(newModelC);
        );


        //OR
        //Populate directly on the resultObject <-im not so sure about this
        tempModelC.populate(path : tempModelC.refId , model :tempModelC.refModel,function(err2,newModelC)
            //Push it into array of modelC Objects
            modelCObjects.push(newModelC);
        )
    );

    //here you have modelCObjects -> Array of populated modelC Objects
);

请务必处理错误。

【讨论】:

以上是关于如果第一个模型为空,如何填充第二个模型的主要内容,如果未能解决你的问题,请参考以下文章

如何在第二个 ViewController 表格视图中使用模型快速显示第一个 ViewController 值

Rails 4 - 根据嵌套形式的第一个选择菜单中的选择动态填充第二个选择菜单

加载第二个模型时,第一个模型的属性会被删除

PHP 如果第一个 var 为空,则使用第二个

如何根据第一个 GridViewComboBoxColumn 的选择填充第二个列

如何在 RecyclerView 适配器中获取第二个模型的位置