You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

POST请求中如何通过object_id关联MongoDB的其他模型?

问题原因

你目前的问题是两处语法错误共同导致的:

  1. Schema字段定义错误
    你给author、publisher字段的type属性嵌套了两层type,相当于错误地将字段类型定义为了一个包含type属性的对象,而非Mongoose的ObjectId类型,导致Mongoose无法自动将传入的id字符串转换为ObjectId格式。
  2. 路由取值逻辑错误
    你在创建Book实例时错误调用了不存在的req.body.author.findById、req.body.publisher.findById属性,请求体中传入的author、publisher本身就是id字符串,直接取值即可,findById是Mongoose模型的查询方法,不存在于请求体参数中。
    另外你原代码的catch块没有声明err参数,报错时会抛出未定义错误。

修复方案

1. 修正Book Schema定义

const mongoose = require('mongoose')

const bookSchema = new mongoose.Schema({
    title: {
        type: String,
        required: true
    }, 
    author: {
        // 直接指定类型为ObjectId,不要嵌套两层type
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'Author',
        required: true // 需要必填的话在这里加
    },
    publisher: {
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'Publisher',
        required: true // 需要必填的话在这里加
    },
    isbn: {
        type: String,
        required: true
    }
})

module.exports = mongoose.model('Book', bookSchema)

2. 修正新增图书路由代码

//Creating one Book
router.post('/', async (req, res) => {
    const book = new Book({
        title: req.body.title,
        // 直接取请求体中的id字符串即可,Mongoose会自动转为ObjectId
        author: req.body.author,
        publisher: req.body.publisher,
        isbn: req.body.isbn
    })

    try {
        const newBook = await book.save()
        // 想要返回关联的作者、出版社信息的话,可以用populate
        // await newBook.populate(['author', 'publisher'])
        res.status(201).json(newBook)
    } catch (err) { // 这里补充err参数
        res.status(400).json({message: err.message})
    }
})

如果担心自动转换失败,可以手动转换格式:author: mongoose.Types.ObjectId(req.body.author),只要传入的字符串是合法的24位十六进制ObjectId格式,就可以转换成功。

内容的提问来源于stack exchange,提问作者char12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:18:00