Mongoose populate () возвращает undefined

Я пытаюсь создать чат с node.js, Express и MongoDB. У меня есть две модели мангуста: для чата и для сообщений.

Модель помещения:

const RoomSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
    },
    owner: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Users',
        required: true,
    },

    messages: {
        type: [mongoose.Schema.Types.ObjectId],
        ref: 'Messages',
        required: true,
    },
    users: {
        type: [mongoose.Schema.Types.ObjectId],
        ref: 'Users',
        required: true,
    },


});

const Room = mongoose.model('Rooms', RoomSchema);

Модель сообщения:


const MessageSchema = new mongoose.Schema({
    text: {
        type: String,
        required: true,
    },
    sendBy: {
        type: String,
        required: true
    }

});

const Messages = mongoose.model('Messages', MessageSchema);

и функция отображения всех сообщений

prepareMessages: function (name, callback) {
        rooms.findOne({
            name: name,
        }).populate('messages')
            .exec(function (err, room) {
                let result = '';
                if (!room) {
                    console.log("Chat does not exist");
                    throw err;
                }
                else {

                    room.messages.forEach(function (item, i, arr) {
                        result += '<dt>' + item.sendBy + '</dt>';
                        result += '<dd>' + item.text + '</dd>';
                    });
                }
                callback(result)
            });
    },

Почему я получаю

TypeError: Cannot read property 'sendBy' of undefined?

Пробовал .populate('rooms.messages'), .populate({path: 'rooms.messages', model:'Messages') и другие варианты, но все равно не работает. Помоги мне, пожалуйста!


person Anya    schedule 08.05.2020    source источник
comment
Вы использовали console.log (room) перед выполнением этой функции forEach, чтобы убедиться, что поля действительно существуют?   -  person Kasey Chang    schedule 08.05.2020
comment
'sendBy' of undefined означает, что item не определено в вашем forEach цикле. Если вы попали внутрь цикла forEach, это означает, что есть массив для итерации, поэтому эта часть работает: room.messages - это массив. Однако по моему опыту, я всегда очень подозрительно относился к тому, что производит Mongoose. Неизменяемые объекты, данные, которые выглядят как JSON, но не являются невидимыми ключами или методами, вы называете это. Попробуйте связать .lean() перед .exec(), чтобы получить необработанные данные, а не чудака Mongoose. Тогда console.log() ваши вещи.   -  person Jeremy Thille    schedule 08.05.2020


Ответы (2)


В схеме комнаты вы определяете сообщения как объект с типом Array of ObjectId, в то время как это должен быть массив элементов, каждый элемент имеет тип ObjectId, сообщения должны быть массивом ObjectIds, а также пользователями.

const RoomSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
    },
    owner: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Users',
        required: true,
    },

    messages: [{ // note here messages is an array
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Messages',
        required: true,
    }],
    users: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Users',
        required: true,
    }],


});

const Room = mongoose.model('Rooms', RoomSchema);

Надеюсь, это поможет

person Mohammed Yousry    schedule 08.05.2020
comment
Спасибо! Оно делает - person Anya; 08.05.2020

  1. sendBy должен иметь тип ObjectId.

const MessageSchema = new mongoose.Schema ({text: {type: String, required: true,}, sendBy: {type: mongoose.Schema.Types.ObjectId, required: true}

});

const Messages = mongoose.model ('Сообщения', MessageSchema);

  1. ref должен быть в нижнем регистре.

    ref: 'Пользователи' следует заменить на ref: 'пользователи'

Аналогично у всех остальных refs

person Mohit Sehgal    schedule 08.05.2020