使用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
相关产品推荐
相关产品推荐

