【问题标题】:Use virtual property to access nested document in Mongoose model使用虚拟属性访问 Mongoose 模型中的嵌套文档
【发布时间】:2016-05-13 07:08:35
【问题描述】:

我试图在我的一个架构中创建一个虚拟项目,这将需要访问此架构中引用的项目所引用的数据(是的,这是 2 个深度引用,连接 3 个架构/模型)

我已尝试使用 Model/Schema A/B/C.. 尽可能地模拟代码。

这将是 ModelA 的架构,其中包含依赖于引用的虚拟项目:

// models/modela.js

// SchemaA for ModelA
const SchemaA = new Schema({
    _foo: {
        // References ModelB
        type: Schema.Types.ObjectId,
        ref: 'ModelB'
    }
})

// Virtual `Modela.something`, which needs the data from ModelC.baz
SchemaA.virtual('something').get(function () {
    // How can I access ModelC.baz
    return 'Value from ModelC'
});

然后是 ModelB 的架构:

// models/modelb.js

// SchemaB for ModelB
const SchemaB = new Schema({
    _bar: [{
        // References ModelC.baz
        type: Schema.Types.ObjectId,
        ref: 'ModelC'
    }]
})

ModelC 的架构:

// models/modelc.js

// SchemaC for ModelC
const SchemaC = new Schema({
    baz: Schema.Types.String
})

正如您在上面看到的,我需要做的是从 ModelA

中的虚拟 something 项目中访问 Modelc.haz

我认为如果我通过查询本身对两个人口都进行了处理,那么也许这会起作用,所以我尝试了类似的方法:

this.find()
    .populate( '_foo' )
    .populate( '_foo._bar' )

这没有用(我实际上并没有真正期望它,但是哦,好吧)

【问题讨论】:

    标签: javascript node.js mongodb mongoose mongoose-populate


    【解决方案1】:

    您可以使用Model.populate 方法来实现:

    ModelA
      .find()
      .populate({
        path: '_foo'
      })
      .exec(function(err, docs) {
        if (err) throw err;
    
        // Populate the '_bar' array of the '_foo' property which is
        // an instance of ModelB
        ModelB.populate(docs[0]._foo, { path: '_bar' }, function(err, result) {
          console.log('Showing ModelC.baz:', docs[0].something);
        });
      });
    

    你可以这样定义虚拟属性:

    SchemaA.virtual('something').get(function () {
        // How can I access ModelC.baz
        return this._foo._bar[0].baz;
    });
    

    【讨论】:

    • 太棒了!谢谢你。我注意到这将在独立文档上运行人口,这意味着一次一个。有没有办法让它填充所有这些?
    • 别在意最后一条评论,我认为它适用于所有人。谢谢!
    • 或许,你可以使用 pre hooks。如果您仍然需要它,请查看我的答案。
    【解决方案2】:

    您可以在this github issue 找到更多信息。您可以使用查询挂钩。

    我有类似的问题,所以我用它来填充参考模型以在虚拟函数中使用。这是一个示例。

    const tutorialSchema = new mongoose.Schema({
        title: {
            type: String,
            required: true
        },
        videos: [
            {
                type: mongoose.Schema.Types.ObjectId,
                ref: 'Video'
            }
        ]
    });
    
    tutorialSchema.pre('findOne', function (next) {
        this.populate('videos');  // now can be accessed using this.videos
        next();
    });
    
    tutorialSchema.virtual('totalTime').get(function () {
        let times = [];
        times = this.videos.map((v) => {
            return v.duration;
        });
        if(times.length === 0) return 0;
        let totalTime; // find total time of videos and then return
        return totalTime;
    });
    

    【讨论】:

      猜你喜欢
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 2012-01-15
      • 2015-05-30
      相关资源
      最近更新 更多