Mongoose Populate не работает

Здравствуйте, у меня есть эта схема (называемая schema.js):

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

var RoomSchema = new Schema({
  name: { type: String, required: true, index: { unique: true } },
  people: { type: Number, required: true },
  childrens: {type: Number, required: true},
  total: {type: Number, required: true}
});

var Room = mongoose.model('Room', RoomSchema);

var AvSchema = new Schema({
  roomId:  {type: Schema.Types.ObjectId, ref: 'Room'},
  people: { type: Number, required: true },
  childrens: {type: Number, required: true},
  total: {type: Number, required: true}
});

var Av = mongoose.model('Av', AvSchema);

module.exports = {
  Room: Room,
  Av: Av
};

в моем файле маршрута:

module.exports = function(app) {
  var model = require('../models/Schema');

  app.get('/api/rooms', function(req, res) {
    model.Room.find(function(err, rooms) {
      if (err)
        res.send(err);

      res.json(rooms);
    });
  });


  app.get('/api/av', function(req, res) {
    model.Av.find().populate('roomId').exec(function(err, av) {
      if (err)
        res.send(err);

      res.json(av);
    });
  });
};

Рисунок db: enter image description here

GET/api/rooms - ответ:

[{
  "_id": "5444d0dd9a31437167eea816",
  "name": "Single",
  "people": 1,
  "childrens": 1,
  "total": 4
}, {
  "_id": "5444d1009a31437167eea817",
  "name": "Double",
  "people": 2,
  "childrens": 2,
  "total": 10
}]

Когда я звоню в api/rooms выглядит нормально, но когда я вызываю api/av, я получил пустой массив [].... Любая идея, что я делаю неправильно? Я должен упомянуть, что я вставил записи в коллекцию av для обеих комнатID

Спасибо заранее.

Ответ 1

По умолчанию Mongoose плюрализует имя модели, чтобы создать имя коллекции, поэтому Mongoose ищет в коллекции avs вместо av.

Вы можете явно задать имя коллекции, передав это как третий параметр в model:

var Av = mongoose.model('Av', AvSchema, 'av');

Ответ 2

Как и в ответе CodyBugstein, я пишу, почему это не сработало в моем случае, хотя это не тот же случай, что и у OP.

Я пытался заполнить поле "pro" моей схемы с помощью .post('save') следующим образом:

mySchema.post('save', function(doc, next) {
    console.log(doc.pro); // Expected to log ObjectID
    doc.populate("pro"); // Populate field
    console.log(doc.pro); // Expected to log actual pro document
}

Однако 2-й console.log также регистрировал ObjectID вместо документа.

Поработав с этим в течение целого часа и попробовав разные подходы, я обнаружил, что все, что мне нужно было сделать, это использовать обещания и вызвать execPopulate() чтобы он возвратил полноценное обещание. Я использовал async/await но вы также можете использовать .then:

mySchema.post('save', async function(doc, next) {
    console.log(doc.pro); // Expected to log ObjectID
    await doc.populate("pro").execPopulate(); // Populate field
    console.log(doc.pro); // Expected to log actual pro document
}

Таким образом, 2-й console.log действительно зарегистрировал весь документ, как и ожидалось :)

Ответ 3

Так как это самый популярный результат для запроса

mongoose populate не работает

Я расскажу, почему он не работал у меня, хотя это не прямой ответ на этот уже разрешенный вопрос, в надежде, что это поможет кому-то

Проблема для меня заключалась в том, что я указал поля в select({..}, но не в поле, которое я пытался заполнить.

Ответ 4

Не забудьте добавить свойство ref в схему для свойства, которое вы пытаетесь заполнить. Например

// ...
const orderSchema = new mongoose.Schema({
  userId: {
    type: Types.ObjectId,
    required: true
  },
  reservationId: {
    type: Types.ObjectId,
    required: true,
    ref: 'Reservation' // <-- don't forget the ref
  }
}, {
  timestamps: true
})
// ...

См мангуста Население

Ответ 5

Для меня проблема была в том, что мне не требовалось заполнять модель в начале файла.