MongoDB updateOne在代码中失效问题的原因排查与修复咨询
问题描述
在使用Mongoose开发时遇到以下问题:
- 回复评论接口中,执行
Upment.updateOne({p_shortId}, {"$push": {"comments": newcomment._id}})无任何效果,将其替换为update方法后功能恢复正常; - 评论接口中,
Post.updateOne({shortId}, {"$push": {"comments": newcomment._id}})可正常执行; - 在MongoDB Compass中执行类似的
updateOne语句也能成功生效。
相关代码与Schema
回复评论接口代码
router.post("/list/:shortId/recomment/:p_shortId", async (req, res, next) => { const { shortId, p_shortId } = req.params; const { comment } = req.body; const email = req.tokenInfo.email; try { const authData = await User.findOne({email}); const postData = await Post.findOne({shortId}); const parentData = await Upment.findOne({p_shortId}); const newcomment = await Downment.create({ postType: 3, author: authData, post_id: postData, parentment_id: parentData, comment: comment }); await Upment.updateOne({p_shortId}, {"$push": {"comments": newcomment._id}}); res.status(200).json({ result: 'recomment success' }) } catch (err) { err.message = `${err.message}, market post recomment error.`; next(err); } });
正常执行的评论接口代码
router.post("/list/:shortId/comment", async (req, res, next) => { const { shortId } = req.params; const { comment } = req.body; const email = req.tokenInfo.email; try { const authData = await User.findOne({email}); const postData = await Post.findOne({shortId}); const newcomment = await Upment.create({ postType: 3, author: authData, post_id: postData, comment: comment }); await Post.updateOne({shortId}, {"$push": {"comments": newcomment._id}}); res.status(200).json({ result: 'comment success' }) } catch (err) { err.message = `${err.message}, market post comment error.`; next(err); } });
MongoDB Compass中可正常执行的语句
db.upments.updateOne({shortId: "wEhPg-wFqS0_2935vuZEQ"}, {"$push": {"comments": new ObjectId("62f38170e3dccbfe7a9842b2")}})
数据Schema定义
import mongoose from "mongoose" import shortId from "./type/shortId.js" const UpmentSchema = new mongoose.Schema({ shortId, comment: String, // closet:1, OOTD:2, board:3 postType: { type: Number, required: true }, author: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, post_id: { type : mongoose.Schema.Types.ObjectId, ref: "Post", required: true }, comments: [{ type: mongoose.Schema.Types.ObjectId, ref: "Downment", }] }, { timestamps: true } ); const DownmentSchema = new mongoose.Schema({ shortId, comment: String, // closet:1, OOTD:2, board:3 postType: { type: Number, required: true }, author: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, post_id: { type : mongoose.Schema.Types.ObjectId, ref: "Post", required: true }, parentment_id: { type : mongoose.Schema.Types.ObjectId, ref: "Upment", required: true }, }, { timestamps: true } ); export const Upment = mongoose.model("Upment", UpmentSchema); export const Downment = mongoose.model("Downment", DownmentSchema);
原因分析
核心问题是查询条件的字段名错误:
- Upment Schema中定义的唯一标识字段是
shortId,但回复评论接口中,无论是查询父评论的Upment.findOne({p_shortId})还是更新的Upment.updateOne({p_shortId}, ...),都使用了p_shortId作为查询键(即{ p_shortId: p_shortId }),这与数据库中存储的字段名不匹配,导致无法找到目标文档,因此updateOne执行后无任何变更。 - 评论接口中的
Post.updateOne({shortId}, ...)使用了正确的字段名(Post Schema中对应字段为shortId),所以能匹配到目标文档并正常更新。 - MongoDB Compass中的语句明确指定了
shortId作为查询键,因此可以成功匹配并执行更新。
至于替换为update方法后生效,推测是旧版Mongoose的update方法存在兼容逻辑(或你在替换时无意中修正了查询字段),但本质上还是查询字段的问题。
修复方案
将回复评论接口中所有针对Upment的查询条件,从{p_shortId}修正为{shortId: p_shortId},具体修改两处:
- 查询父评论的代码:
// 原代码 const parentData = await Upment.findOne({p_shortId}); // 修改为 const parentData = await Upment.findOne({shortId: p_shortId});
- 更新父评论的代码:
// 原代码 await Upment.updateOne({p_shortId}, {"$push": {"comments": newcomment._id}}); // 修改为 await Upment.updateOne({shortId: p_shortId}, {"$push": {"comments": newcomment._id}});
修改后,updateOne就能正确匹配到目标Upment文档,执行$push操作将子评论ID添加到comments数组中。
内容的提问来源于stack exchange,提问作者RunningLearner
相关产品推荐
相关产品推荐

