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

Mongoose Category模型添加关联Product虚拟字段报错及空结果问询

问题1报错修复

你出现TypeError: Cannot use 'in' operator to search for 'transform' in true的原因是Schema配置项中toJSON、toObject的取值错误,不能直接赋值为true,需要传入配置对象,若要虚拟字段正常序列化返回,还需要开启virtuals: true属性。

问题2关联查询无结果修复

你当前$lookup的关联字段写反,同时虚拟字段getter的实现逻辑存在三处错误:

  • 不能直接调用Schema的aggregate方法,需要调用Model的方法
  • 关联逻辑颠倒:Category集合的_id对应Product集合的category字段,所以localField应该是Category的_id,foreignField是Product的category
  • Mongoose虚拟字段默认不支持异步getter的结果序列化,如果你需要统计分类下的商品数量,更推荐使用Mongoose内置的虚拟关联配置实现,比手写聚合逻辑更稳定

修复后完整代码

// PRODUCT MODEL 无需修改
const productSchema = new mongoose.Schema(
  {
    category: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Category",
    },
    name: {
      type: String,
      required: true,
    },
    price: {
      type: Number,
      required: true,
      default: 0,
    },
    colors: [
      {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Color",
      },
    ],
    sizes: {
      type: Array,
      default: [
        { id: 1, size: "XS" },
        { id: 2, size: "S" },
        { id: 3, size: "M" },
        { id: 4, size: "L" },
        { id: 5, size: "XL" },
        { id: 6, size: "XXL" },
      ],
    },
  },
  { timestamps: true }
);


const Product = mongoose.model("Product", productSchema);
export default Product;

// CATEGORY MODEL 修复后代码
const CategorySchema = new mongoose.Schema(
  {
    name: String,
  },
  { 
    timestamps: true, 
    // 修复toJSON/toObject配置,开启虚拟字段序列化
    toJSON: { virtuals: true }, 
    toObject: { virtuals: true } 
  }
);

// 配置count虚拟字段,直接返回对应分类的商品数量
CategorySchema.virtual("count", {
  ref: "Product",
  localField: "_id",
  foreignField: "category",
  count: true // 开启后直接返回匹配数量,不会返回完整商品列表
});

// 可选:配置items虚拟字段,返回对应分类的完整商品列表
CategorySchema.virtual("items", {
  ref: "Product",
  localField: "_id",
  foreignField: "category",
});

const Category = mongoose.model("Category", CategorySchema);
export default Category;

使用示例

查询时需要手动populate虚拟字段才能拿到对应值:

// 查询所有分类同时返回每个分类的商品数量
const categories = await Category.find().populate('count');
// 查询所有分类同时返回每个分类的商品列表+数量
const categoriesWithProducts = await Category.find().populate('count').populate('items');

内容的提问来源于stack exchange,提问作者john otor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:06:03