Почему MongooseJS неправильно заполняет мои поля?

Я пытаюсь адаптировать пример здесь

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

Я удалил истории и вместо этого пытаюсь добавить поле «друзья». Мой код выглядит следующим образом

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();

            });            

        });

    });

});

Он печатает следующий текст

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: [] } ] }

Другими словами, он распечатывает объект «Чарли». Моя желаемая функциональность заключается в том, чтобы MongooseJS использовал ObjectIds в поле друзей и заполнил массив соответствующими объектами (aaron и bill). Другими словами, что-то большее в духе

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

Что я делаю не так?


person deltanovember    schedule 16.05.2012    source источник


Ответы (1)


Вы не делаете ничего плохого. Это по дизайну. Запрос представляет собой findOne для Чарли, заполняется, а затем выполняет еще один запрос, чтобы вернуть документы из коллекции ref.

Самое близкое, что вы можете получить, это добавить select к запросу, чтобы вернуть только друзей:

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();
  }); 

Что вернет:

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