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

MongoDB创建Product前用聚合校验categoryId存在性,无需导入CategoryModel

解决方案:在创建产品前验证分类存在性(无需控制器导入分类模型)

可以通过**Mongoose预保存中间件(pre-save hook)**结合聚合操作实现需求,无需在ProductController中导入CategoryModel,所有验证逻辑放在Schema层面处理。

实现步骤

在productSchema中添加预保存中间件,利用Mongoose的this.model('Category')直接获取分类模型,再通过聚合操作检查分类是否存在:

const productSchema = new mongoose.Schema({
  name: { type: String, required: true },
  price: { type: Number, required: true },
  addedBy: { type: mongoose.Types.ObjectId, ref: 'User' },
  categoryId: { type: mongoose.Types.ObjectId, ref: 'Category' },
  isDeleted: { type: Boolean, default: false },
},
{ 
  timestamps: true,
  versionKey: false 
});

// 添加预保存中间件,验证分类存在性
productSchema.pre('save', async function(next) {
  // 如果未传入categoryId,直接跳过检查
  if (!this.categoryId) return next();

  // 使用聚合操作检查目标分类是否存在(排除已删除的分类)
  const checkResult = await this.model('Category').aggregate([
    {
      $match: {
        _id: this.categoryId,
        isDeleted: false
      }
    },
    { $count: 'exists' }
  ]);

  // 若聚合结果为空,说明分类不存在,抛出错误阻止保存
  if (checkResult.length === 0) {
    return next(new Error('指定的分类不存在或已被删除'));
  }

  // 分类验证通过,继续执行保存流程
  next();
});

代码说明

  1. 无需导入CategoryModel:通过this.model('Category')可以直接从Mongoose的模型注册表中获取分类模型,避免在控制器或Schema文件外显式导入。
  2. 聚合逻辑:
    • $match:匹配传入的categoryId,同时排除isDeleted: true的已删除分类
    • $count:统计匹配到的文档数量,若结果数组长度为0,说明没有符合条件的分类
  3. 异步处理:中间件使用async/await处理异步聚合查询,确保验证完成后再执行保存操作。

替代方案(更简洁)

如果不需要严格使用聚合操作,也可以用countDocuments实现相同效果,代码更简洁:

productSchema.pre('save', async function(next) {
  if (!this.categoryId) return next();

  const categoryCount = await this.model('Category').countDocuments({
    _id: this.categoryId,
    isDeleted: false
  });

  if (categoryCount === 0) {
    return next(new Error('指定的分类不存在或已被删除'));
  }

  next();
});

使用方式

在ProductController中正常调用产品创建逻辑即可,验证逻辑会自动触发:

// 控制器中无需导入CategoryModel
const createProduct = async (req, res) => {
  try {
    const product = await Product.create(req.body);
    res.status(201).json(product);
  } catch (err) {
    res.status(400).json({ message: err.message });
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 02:38:09