0

I'm testing out an idea and have made some contrived examples for discussion.

I have the following schema's models:

var outerSchema = new Schema({
    title: String,
    refD: [{type: Schema.ObjectId, ref: 'InnerOne'},
           {type: Schema.ObjectId, ref: 'InnerTwo'}]
});

var innerOneSchema = new Schema({
    title: String
});

var innerTwoSchema = new Schema({
    turtle:String
});

var Outer = mongoose.model('Outer', outerSchema);
var InnerOne = mongoose.model('InnerOne', innerOneSchema);
var InnerTwo = mongoose.model('InnerTwo', innerTwoSchema);

I have successfully pushed an example of each of these to Mongo. This has resulted in three collections with a refD array that includes the ObjectId's of the innerOne and innerTwo objects, looking good from mongo's point of view:

{
    "_id" : ObjectId("56625b7c752995f505637864"),
    "title" : "LOOK AT MY CHILDREN!",
    "refD" : [
        ObjectId("56625b7c752995f505637862"),
        ObjectId("56625b7c752995f505637863")
    ],
    "__v" : 1
}

However when I use the populate command as so:

Outer
    .findOne({title: 'LOOK AT MY CHILDREN!'})
    .populate('refD')
    .exec(function(err,res){
        if(err) console.log(err);

        console.log(res);
    });

the result is as follows:

{ refD: 
   [ { __v: 0,
       title: 'Im the first type inside!',
       _id: 56625b7c752995f505637862 } ],
  __v: 1,
  title: 'LOOK AT MY CHILDREN!',
  _id: 56625b7c752995f505637864 }

So structurally this is correct however it looks as though the populate function has only populated the first of the two types.

Am I pushing the limits of what can be performed or is there a way to handle the population of different objects?

I had considered using discriminators to make ALL models children of a single parent class but I would prefer not to, if I do that I may as well use a relational database.

------EDIT------ At this point it doesn't seem like this is doable without modifying or creating a plug in.

For anyone who was thinking the same thing I decided for now I would go back to a more traditional approach, I've created a relatedRecordSchema that stores an Id and a record type and some other useful metadata. This essentially pushes the logic for population up to the app.

In my use case this isn't so bad as I don't always want to populate all of the various related records but for the application or user to decide on the fly.

This isn't an answer so I will leave the question open hoping someone takes the initiative and builds a plugin ;)

Cheers B

delProfundo
  • 110
  • 1
  • 7

1 Answers1

0

To my knowledge populate works for one Schema. You could try to run the populate two times to the 'refD' by giving different model parameter.

More information about populate: Mongoose populate

I didn't test this through, but possible way to solve this problem:

Outer
.findOne({title: 'LOOK AT MY CHILDREN!'})
.populate({
  path: 'refD',
  model: 'InnerOne'
})
.populate({
  path: 'refD',
  model: 'InnerTwo'
})
.exec(function(err,res){
    if(err) console.log(err);

    console.log(res);
});
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Mikko Johansson
  • 235
  • 1
  • 8
  • hmmm. Unfortunately no this doesn't work, whichever populate comes second is singularly present in the array. So it seems you can push as many models in there you like but can only populate one out at a time. I'll keep playing. Thanks – delProfundo Dec 07 '15 at 07:19