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

Mongoose查询时如何直接将Object Id转为String?解决Next.js传参警告

解决Next.js 13 Server Component传递Mongoose查询结果到Client Component的类型问题

你遇到的问题是因为lean()虽然把Mongoose Document转为普通对象,但_id仍是ObjectId实例、date仍是Date对象,这两类对象都带有toJSON方法,不符合Next.js要求的原始类型纯对象规范。下面是几种直接可行的解决方法:

方法一:手动映射转换字段(最直接)

在查询结果返回前,手动把_id转为字符串、date转为ISO字符串(或时间戳):

async function getData() {
  await dbConnect()
  const rawData = await Weight.find().lean()
  
  // 转换每个文档的特殊字段
  return rawData.map(item => ({
    ...item,
    _id: item._id.toString(), // ObjectId转字符串
    date: item.date.toISOString() // Date对象转ISO格式字符串
  }))
}

方法二:用MongoDB聚合查询直接转换

在数据库层面就把_id和日期转成字符串,避免前端额外处理:

async function getData() {
  await dbConnect()
  return await Weight.aggregate([
    {
      $project: {
        _id: { $toString: '$_id' }, // 数据库端将ObjectId转为字符串
        weight: 1,
        date: { $dateToString: { format: "%Y-%m-%dT%H:%M:%S", date: "$date" } }, // 自定义日期格式
        __v: 1
      }
    }
  ])
}

方法三:全局配置Mongoose钩子(一次配置通用)

在Weight模型的Schema里添加查询后钩子,自动转换字段,所有查询都会生效:

// 假设你的Weight Schema定义如下
const WeightSchema = new mongoose.Schema({
  weight: Number,
  date: Date
})

// 添加post查询钩子,处理find方法返回的结果
WeightSchema.post('find', function(docs) {
  docs.forEach(doc => {
    doc._id = doc._id.toString()
    doc.date = doc.date.toISOString()
  })
})

const Weight = mongoose.model('Weight', WeightSchema)

之后再调用Weight.find().lean()时,返回的结果就已经是处理好的纯原始类型对象了。

注意:如果你的查询还用到findOne等其他方法,需要对应添加findOne的post钩子。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:12:54