Can't get Mongoose.js Subdocument Array to pop

2020-05-21 04:57发布

I'm using mongoose.js on a node.js server connecting to mongodb and I have a mongoose model like the following

SubSchema = new Schema({
    _member:     {type: ObjectId, ref: 'Member'},
    members:     [{type: ObjectId, ref: 'Member'}],
    created:     { type: Date, default: Date.now }
});
mongoose.model('SubModel', SubSchema);

MainSchema = new Schema({
    _member:     {type: ObjectId, ref: 'Member'},
    subs:        [SubSchema],
    members:     [{type: ObjectId, ref: 'Member'}],
    created:     { type: Date, default: Date.now }
});
var MainModel mongoose.model('MainModel', MainSchema);

which i pull with a command like this

var q = MainModel.find({})
                 .sort('created', -1)
                 .limit(25)
                 .populate("_member")
                 .populate("subs._member")
                 .populate("subs.members");

q.execFind(function(err, mains){
    //mains[0].subs[0].members - will always be empty why?
});

my problem is that i can't get subs.members array to populate or even load, it just keeps showing as an empty array.

I've tried .populate("subs.members") to no avail even though subs._member loads just fine

5条回答
【Aperson】
2楼-- · 2020-05-21 05:32

I had several nest layers deep of sub docs, and none of the supplied options worked for me. I found this amazing Mongoose plugin that will do deep population seamlessly. You just use the same syntax you would expect to work with populate, but it actually works.

https://github.com/buunguyen/mongoose-deep-populate

查看更多
Root(大扎)
3楼-- · 2020-05-21 05:36

Follow-up on @JohnnyHK's post, you can specify the Model to use in populate() for now:

https://github.com/LearnBoost/mongoose/issues/1377#issuecomment-15920370

查看更多
Luminary・发光体
4楼-- · 2020-05-21 05:41

I have something that looks a slightly different but populates the document with the array items. I'm wondering if it's the objectid's that are causing the issues.

var mongoose = require('mongoose');
var Schema = mongoose.Schema, ObjectID = Schema.ObjectId;

var SubSchema = new Schema({
    testsub: String,       
    created: { type: Date, default: Date.now }
});

var MainSchema = new Schema({
    test: String
    subs: [SubSchema],
    created: { type: Date, default: Date.now }
});

mongoose.model('MainSchema', MainSchema, mainschema);

var query = MainSchema.find({});
查看更多
▲ chillily
5楼-- · 2020-05-21 05:49

try this

    SubSchema = new Schema({
        _member:     {type: ObjectId, ref: 'Member'},
        members:     [{type: ObjectId, ref: 'Member'}],
        created:     { type: Date, default: Date.now }
    });
    var SubModel = mongoose.model('SubModel', SubSchema);//add

    MainSchema = new Schema({
        _member:     {type: ObjectId, ref: 'Member'},
        subs:        [SubSchema],
        members:     [{type: ObjectId, ref: 'Member'}],
        created:     { type: Date, default: Date.now }
    });

    var MainModel = mongoose.model('MainModel', MainSchema);

    MainModel.find({})
             .sort('created', -1)
             .limit(25)
             .populate("_member")
             .populate("subs._member")
             .exec(function(err, mains){

                 //add
                 SubModel.populate(mains,{
                     path:'subs.members'
                 },function(err,mains){
                    //mains[0].subs[0].members - is not empty
                 });
             });
查看更多
神经病院院长
6楼-- · 2020-05-21 05:55

@leesei: I can't comment on your post (too little rep), so I leave this as a separate answer.

In mongoose 3.6 subdoc population still doesn't work, the issue github.com/LearnBoost/mongoose/issues/1381 has been closed 7 months ago with the following solution as a workaround. I had to change it slightly to merge the populated subdocument back to the main document.

The subdocument's model Story has to be specified explicitly:

Person.findById(user1._id).populate("stories")
    .exec(function(err, doc {
         Story.populate(doc.stories, {path: 'creator'}, function (err, stories) {
             doc.stories = stories;
             return doc;
         })
})

In the solution above this works:

Story.populate(doc.stories, {path: 'creator'}, callback)

but this still won't work:

Story.populate(doc, {path: 'stories.creator'}, callback)
查看更多
登录 后发表回答