简体   繁体   English

如何在子文档中填充模型实例数组? MongoDB 猫鼬

[英]How to populate an array of model instances inside a subdocument? MongoDB Mongoose

I have a subdocument that is nested as an array.我有一个嵌套为数组的子文档。 Inside that subdocument I have references to other models.在该子文档中,我引用了其他模型。 Using the .Find and .Populate methods I can receive the entire objects for single models referenced in the subdocument (check out Stop below) but not an array of model instances, Facts/Recommendations.使用.Find.Populate方法,我可以接收子文档中引用的单个模型的整个对象(请查看下面的停止),但不能接收模型实例数组、事实/建议。 For Facts/Recommendations I receive an array of object _ids .对于事实/建议,我收到一组对象_ids I can probably just take those _ids and make another query but this seems messy.我可能只需要那些_ids并进行另一个查询,但这看起来很混乱。

Is there a way to populate the array?有没有办法填充数组? Do I need to use Aggregate + $lookup?我需要使用 Aggregate + $lookup 吗? Is there a more Mongo way to restructure the Schema to simplify this?是否有更多的 Mongo 方法来重构架构以简化这一点?

Thank you for all and any help!谢谢大家和任何帮助!

My subdocument called TourStop:我的子文档名为 TourStop:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const TourStopSchema = new Schema({
    stop: {
        type: Schema.Types.ObjectId,
        ref: 'Stop',
        required:[true, 'must have a Stop'],
    },
    mandatory: {
        type:Boolean,
        default: false
    },
    check_in_time: {
        type: Number,
        default: 0
    },
    order: {
        type:Number,
        required: [true, 'Must have an order']
    },
    facts: [{
        type: Schema.Types.ObjectId,
        ref: 'Fact'
    }],
    recommendations: [{
        type: Schema.Types.ObjectId,
        ref: 'Recommendation'
    }]
});


module.exports = TourStopSchema;

TourStops lives inside of Tour: TourStops 住在 Tour 内:

const mongoose = require('mongoose');
const TourStopSchema = require('../subdocs/tour_stop');
const Schema = mongoose.Schema;

const tourSchema = new Schema({
    name: {
        type:String,
        required:[true,'Name is required!'],
        unique: true
    },
    city: {
        type: String,
        required: [true, 'City is required!']
    },
    tourStops:[TourStopSchema]
});

const Tour = mongoose.model('Tour', tourSchema);
module.exports = Tour;

Stop Schema which is populated just fine. Stop Schema 填充得很好。

const mongoose = require('mongoose');
const LocationSchema = require('../subdocs/location');
const ImageSchema = require('../subdocs/image');
const Schema = mongoose.Schema;

const stopSchema = new Schema({
    name:{
        type: String,
        required:[true,'Must have a name!']
    },
    location:LocationSchema,
    categories: {
        type: [String],
        default:[]
    },
    images:{
        type:[ImageSchema],
        default:[]
    }
});

const Stop = mongoose.model('Stop', stopSchema);
module.exports = Stop; 

And Fact Schema which is not populated correctly, instead returns an array of strings with the _ids以及未正确填充的事实架构,而是返回带有 _ids 的字符串数组

Fact:事实:

const mongoose = require('mongoose');
const ImageSchema = require('../subdocs/image');
const Schema = mongoose.Schema;

const factSchema = new Schema({
    stop: {
        type: Schema.Types.ObjectId,
        ref:'Stop',
        required:[true, 'A Fact must have a Stop!'],
    },
    description: {
        type: String,
        required: [true,'A Fact must have a description!']
    },
    images: {
        type:[ImageSchema],
        default:[]
    }
});

const Fact = mongoose.model('Fact', factSchema);
module.exports = Fact;

And I'm running a test to check that the schema is properly hooked up to retrieve all the attributes of a TourStop:我正在运行测试以检查模式是否正确连接以检索 TourStop 的所有属性:

it('saves a full relation graph', (done) => {
    User.findOne({ first_name: 'Dean' })
        .populate({
            // in that user find the tours property and load up all tours
            path: 'tours',
            // inside of all those tours, find the tourstops property and load all associated stops
            populate: {
                path: 'tour_stops.facts',
                model: 'Fact'
            },
            populate: {
                path: 'tour_stops.stop',
                model: 'Stop'
            }
        })
        // .populate('tours.tour_stops[0].facts')
        .then((user) => {
            // console.log(user.tours[0].tour_stops[0].stop);
            console.log(user.tours[0].tour_stops[0]);
            // console.log(Array.isArray(user.tours[0].tour_stops[0].facts))
            assert(user.first_name === 'Dean' );
            assert(user.tours.length === 1);
            assert(user.tours[0].name === "Awesome New Tour");
            assert(user.tours[0].tour_stops[0].stop.name === 'Jaffa Clock Tower');
            // assert(user.tours[0])
            // assert(user.blogPosts[0].title === 'JS is Great');
            // assert(user.blogPosts[0].comments[0].content === 'Congrats on great post!' );
            // assert(user.blogPosts[0].comments[0].user.name === 'Joe' )
            done();
        })
    })

You can use the following code to populate tours, stop, facts and recommendations.您可以使用以下代码来填充游览、停靠点、事实和建议。 Note in model property, we should not give string value, but the model itself.注意在model属性中,我们不应该给出字符串值,而是模型本身。 So you need to import them to your code.所以你需要将它们导入到你的代码中。

  User.findOne({ first_name: "Dean" })
    .populate({
      path: "tours",
      populate: {
        path: "tourStops.stop",
        model: Stop
      }
    })
    .populate({
      path: "tours",
      populate: {
        path: "tourStops.facts",
        model: Fact
      }
    })
    .populate({
      path: "tours",
      populate: {
        path: "tourStops.recommendations",
        model: Recommendation
      }
    })
    .then(user => {
       console.log(user);
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM