Неправильная популяция после document.save () в мангусте - PullRequest
1 голос
/ 29 февраля 2020

Я пытаюсь создать блог и вернуть заполненный блог в следующих схемах:

const blogSchema = new mongoose.Schema({
    title: {
        type:String
    },
    author: {
        type: mongoose.Schema.Types.ObjectID,
        ref: 'UserTable',
        required: true
    }
});
module.exports = mongoose.model('BlogPostTable', blogSchema);

И

const userSchema = new mongoose.Schema({
    username:{
        type:String,
    },
    blogPosts: [
        {
            type: mongoose.Schema.Types.ObjectID,
            ref: 'BlogPostTable'
        }
    ]
});
module.exports = mongoose.model('UserTable', userSchema);

Я сохраняю блог следующим образом:

blogRouter.post('/', async (request, response, next) => {

    const token = request.token;

    try {
        const foundUser = await userTable.findById(decodedToken.id); // Find User

        const newBlog = new blogTable({                              // Create document 
            title: request.body.title,
            text: request.body.text,
            likes: 0,
            author: foundUser._id
        });

        await newBlog.save();  // Save Blog 
        foundUser.blogPosts = foundUser.blogPosts.concat(newBlog); // update Users blogs 
        await foundUser.save(); 
        response.status(200).json(newBlog.populate('author').toJSON()); // WRONG OUTPUT 
    }

Однако , Автор заполнен неправильно. Нет username, а id - это массив!

Где я go ошибся и как это исправить?

1 Ответ

1 голос
/ 29 февраля 2020

Вы можете добавить строку кода ниже, чтобы увидеть, что происходит в вашем коде:

mongoose.set('debug', true);

Первое утверждение: await newBlog.save(); запускает операцию insertOne с документом, имеющим author set: author: ObjectId("...")

, затем вы запускаете await foundUser.save();, который явно устанавливает массив блогов:

{ '$set': { blogPosts: [ ObjectId(...), ObjectId(...) ] }

Это имеет смысл, потому что вы использовали concat в JS коде. Дело в том, что другого третьего запроса нет, потому что вы пытаетесь запустить populate для существующего объекта в памяти, который не будет работать - для заполнения требуется запрос вместо объекта в памяти.

придется запросить вашу базу данных снова, чтобы получить author заполнено:

let userPosts = await blogTable
        .find({ author: foundUser._id })
        .populate('author');

console.log(userPosts);

, что вызывает два запроса:

Mongoose: blogposttables.find({ author: ObjectId("...") }, { projection: {} })
Mongoose: usertables.find({ _id: { '$in': [ ObjectId("...") ] } }, { projection: {} })
...