deltanovember
deltanovember

Reputation: 44051

Why doesn't MongooseJS correctly populate my fields?

I'm trying to adapt the example here

http://mongoosejs.com/docs/populate.html

I have removed stories and am trying to add a 'friends' field instead. My code is as follows

var PersonSchema = new Schema({
    name    : String
  , age     : Number
  , friends : [{ type: Schema.ObjectId, ref: 'Person' }]
});

var Person = mongoose.model('Person', PersonSchema);

var aaron = new Person({ name: 'Aaron', age: 100 });
var bill = new Person({ name: 'Bill', age: 97 });

aaron.save(function (err) {
    if (err) throw err;
    bill.save(function(err) {
        if (err) throw err;
        var charlie = new Person({ name: 'Charlie', age: 97, friends: [aaron._id, bill._id] });
        charlie.save(function(err) {
            if (err) throw err;
            Person
            .findOne({name: 'Charlie'})
            .populate('friends')
            .run(function(err, friends) {
                if (err) throw err
                console.log('JSON for friends is: ', friends);
                db.disconnect();

            });            

        });

    });

});

It prints out the following text

JSON for friends is:  { name: 'Charlie',
  age: 97,
  _id: 4fb302beb7ec1f775e000003,
  stories: [],
  friends:
   [ { name: 'Aaron',
       age: 100,
       _id: 4fb302beb7ec1f775e000001,
       stories: [],
       friends: [] },
     { name: 'Bill',
       age: 97,
       _id: 4fb302beb7ec1f775e000002,
       stories: [],
       friends: [] } ] }

In other words it is printing out the 'charlie' object. My desired functionality is for MongooseJS to use ObjectIds in the friends field and populate an array with the matching objects (aaron and bill). In other words something more along the lines of

[ { name: 'Aaron',
       age: 100,
       _id: 4fb302beb7ec1f775e000001,
       stories: [],
       friends: [] },
     { name: 'Bill',
       age: 97,
       _id: 4fb302beb7ec1f775e000002,
       stories: [],
       friends: [] } ]

What am I doing wrong?

Upvotes: 1

Views: 1032

Answers (1)

aaronheckmann
aaronheckmann

Reputation: 10780

You are not doing anything wrong. This is by design. The query is a findOne for Charlie, populate then does another query to return the documents from the ref collection.

The closest you can get is by adding a select to the query to only return the friends:

Person
  .findOne({name: 'Charlie'})
  .select('friends')
  .populate('friends')
  .run(function(err, friends) {
    if (err) throw err
    console.log('JSON for friends is: ', friends);
    db.disconnect();
  }); 

Which would return:

JSON for friends is:  
{ 
  _id: 4fb302beb7ec1f775e000003,
  friends:
    [ { name: 'Aaron',
        age: 100,
        _id: 4fb302beb7ec1f775e000001,
        stories: [],
        friends: [] },
      { name: 'Bill',
        age: 97,
        _id: 4fb302beb7ec1f775e000002,
        stories: [],
        friends: [] } ] }

Upvotes: 3

Related Questions