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

使用Mongoose的findOneAndUpdate更新对象数组时遇类型转换错误

问题原因与解决方案

错误本质

你的UserSchema中,watched_movies_list数组里的movie_meta_data字段被定义为Schema.Types.ObjectId,它要求存储关联的MovieDataSchema文档的ID值,但你当前尝试推送的是完整的电影对象(包含title、overview等字段),Mongoose无法将整个对象转换为ObjectId类型,因此抛出了CastError。

解决方案分两种场景:

场景1:需要关联MovieDataSchema文档(推荐用于数据复用/关联查询)

如果MovieDataSchema对应的集合中已有该电影数据,或需要先创建文档再关联,按以下步骤操作:

try {
  // 假设用第三方电影ID(如tmdb的id)作为唯一标识查找电影
  let movieData = await MovieData.findOne({ id: watchedMovie.id });
  
  // 若不存在则创建新的MovieData文档
  if (!movieData) {
    movieData = await MovieData.create({
      title: watchedMovie.title,
      overview: watchedMovie.overview,
      poster_path: watchedMovie.poster_path,
      original_title: watchedMovie.original_title,
      original_language: watchedMovie.original_language,
      id: watchedMovie.id,
      release_date: watchedMovie.release_date,
      genre_ids: watchedMovie.genre_ids
    });
  }

  // 使用MovieData的_id更新用户的观影列表
  const user = await User.findOneAndUpdate(
    { _id: req.body.id },
    { 
      $push: { 
        watched_movies_list: { 
          movie_meta_data: movieData._id, 
          rating: watchedMovie.rating 
        } 
      } 
    },
    { new: true } // 添加此选项返回更新后的用户文档,默认返回更新前的旧数据
  );

  res.status(200).json({
    success: 'true',
    user: user
  });
} catch (err) {
  res.status(400).json(err);
  throw err;
}

场景2:直接存储电影元数据(无需关联文档)

如果业务不需要复用电影数据,只想在用户文档中直接存储完整电影信息,修改UserSchema定义即可:

watched_movies_list: [{
  movie_meta_data: {
    title: String,
    overview: String,
    poster_path: String,
    original_title: String,
    original_language: String,
    id: Number,
    release_date: String,
    genre_ids: Array
  },
  rating: { type: Number }
}]

修改后,你原来的更新代码可直接使用,此时movie_meta_data接受完整的电影对象。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:35:33