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

如何解决Mongoose获取的MongoDB子文档_id传入EJS时报错的问题

问题根因

你遇到的问题有两个核心原因:

  1. 直接通过Mongoose查询拿到的子文档是被代理的Mongoose文档实例,不是普通JS对象,内部属性受Mongoose管控,直接修改、删除属性都不会生效
  2. ObjectId类型的_id传递到EJS后,如果直接在<script>标签中使用,没有被包裹为合法字符串的话就会触发语法错误

可行解决方案

方案1:将子文档转为普通JS对象后再处理

这是最通用的方案,转成普通对象后可以随意修改或删除字段:

Hiker.findById(id, (err, hiker) => {
  const hike = hiker.log.id(hikeId)
  // 调用toObject()转为普通JS对象,解除Mongoose代理
  const plainHike = hike.toObject()
  // 转为字符串
  plainHike._id = plainHike._id.toHexString()
  // 如果要删除字段直接用:delete plainHike._id
  res.render('editHike', { data: plainHike })
})

方案2:查询时直接返回普通对象

查询时加上lean()方法,整个查询结果都会返回纯JS对象,不需要额外转换:

// 加lean() + exec() 拿到纯JS格式的查询结果
Hiker.findById(id).lean().exec((err, hiker) => {
  const hike = hiker.log.find(item => item._id == hikeId)
  // 此时hike已经是普通对象,可直接修改
  hike._id = hike._id.toString()
  res.render('editHike', { data: hike })
})

方案3:直接在EJS侧处理

如果不想修改后端逻辑,也可以在EJS中使用时做兼容,尤其是在<script>标签中使用时一定要加引号包裹:

<!-- 普通场景直接使用 -->
<p>徒步记录ID:<%= data._id %></p>

<!-- JS脚本中使用 -->
<script>
// 外层加单引号把ObjectId转为字符串,避免语法错误
const hikeId = '<%= data._id %>'
// 也可以主动调用转字符串方法
const hikeId = '<%= data._id.toString() %>'
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:24:04