Node.js使用Mongoose向数组属性push数据后数据库返回空数组问题
问题原因及修复方案
核心问题点
- 异步逻辑顺序错误:
product.save()是异步IO操作,你当前的代码中分类更新逻辑和产品保存逻辑并行执行,且产品保存成功后直接跳转响应,没有等待分类更新操作执行完成,很容易出现更新逻辑中断不执行的问题 - findOneAndUpdate默认返回更新前的旧文档:你控制台打印的result是修改前的分类数据,无法直观判断是否更新成功,需要配置参数返回更新后的新文档
- 产品Schema类型错误:Mongoose没有内置
Float类型,价格字段定义错误会导致产品保存失败,连带后续关联更新逻辑异常
修复后的代码
首先修正产品Schema的价格字段:
var productSchema = new mongoose.Schema({ productName: { type: String, unique: true, required: [true, 'Product name is required'] }, productCategory: { type: String, ref: 'categorySchema', required: [true, 'Category name is required'] }, // 修正Float为Number,Mongoose无原生Float类型,小数直接用Number存储 productPrice: { type: Number, required: [true, 'Price name is required'] }, productQuantity: { type: Number, required: [true, 'Quantity name is required'] }, productSection: { type: String, required: [true, 'Section name is required'] }, productExDate: { type: String, required: [true, 'ExDate name is required'] } }) const productDB = mongoose.model('productSchema', productSchema);
然后修正接口的异步逻辑,把分类更新放到产品保存成功的回调中,确保逻辑顺序正确:
const productObject = new productSchema({ productName: req.body.productName, productPrice: req.body.productPrice, productCategory: req.body.productCategory, productQuantity: req.body.productQuantity, productSection: req.body.productSection, productExDate: req.body.productExDate }) productObject.save() .then(savedProduct => { // 产品保存成功后再执行分类更新操作,新增{new: true}返回更新后的数据 return categoryDB.findOneAndUpdate( { categoryName: savedProduct.productCategory }, { $push: { productsCategory: savedProduct._id } }, { new: true } ) }) .then(updatedCategory => { console.log('更新后的分类数据:', updatedCategory) res.redirect('/halalMunchies/all-products'); }) .catch(err => { res.status(500).send({ message: err.message || "Some error occured while creating a create operation" }); });
额外验证点
如果修改后还是为空,可以优先检查两点:
- 确认
req.body.productCategory的值和数据库中已存在的categoryName完全一致,注意大小写、空格等字符差异,查询条件不匹配会导致更新不生效 - 检查Mongoose版本是否存在
$push操作的兼容性问题,低版本可以尝试用{ $addToSet: { productsCategory: savedProduct._id } }替代,避免重复插入相同id
内容的提问来源于stack exchange,提问作者Hesham Eldawy
相关产品推荐
相关产品推荐

