NestJS中Mongoose嵌套Label的Product查询返回空数组问题
问题:查询关联Label名称为'Something'的Product返回空数组
我在Product文档中关联了Label文档,尝试用以下代码查询所有Label名称为'Something'的Product文档,但返回结果是空数组:
return this.productModel.find({ 'label.name': 'Something', });
以下是LabelSchema.ts和ProductSchema.ts的定义:
LabelSchema.ts
@Schema({ versionKey: false, timestamps: true }) export class Label extends Document { @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }) user: User; @Prop({ type: String, required: true }) name: string; @Prop({ type: String, default: null }) email: string | null; @Prop({ type: String, default: null }) description: string; @Prop({ type: SocialSchema, default: new Social() }) socials: Social; @Prop({ type: String, enum: LabelStatus, default: LabelStatus.Draft }) status: string; // TODO add FILE document @Prop({ type: String, default: null }) avatar: any; // TODO add FILE document @Prop({ type: String, default: null }) header: any; @Prop({ type: Number, default: process.env.APP_DEFAULT_COMMISSION_RATE, }) commissionRate: number; @Prop({ type: Number, default: 0 }) earnings: number; @Prop({ type: String, required: true }) slug: string; @Prop({ type: Date, required: true }) createdAt: Date; @Prop({ type: Date, required: true }) updatedAt: Date; }
ProductSchema.ts
@Schema({ versionKey: false, timestamps: true, }) export class Product extends Document { @Prop({ type: String, required: true }) name: string; @Prop({ type: String, enum: ProductStatus, default: ProductStatus.Draft }) status: string; @Prop({ type: mongoose.Schema.Types.ObjectId, ref: Label.name, autopopulate: true, }) label: Label; @Prop({ type: String, default: '' }) shortDescription: string; @Prop({ type: String, default: '' }) description: string; @Prop({ type: Number, default: null }) price: number | null; @Prop({ type: Number, default: null }) salePrice: number | null; @Prop({ type: Boolean, default: false }) isFree: boolean; //TODO add FILE document artwork: any; //TODO add FILE document audioPreview: any; @Prop([ { type: mongoose.Schema.Types.ObjectId, ref: Category.name, autopopulate: true, }, ]) category: Category[]; @Prop({ type: Boolean, default: false }) featured: false; @Prop({ type: String, required: true }) slug: string; @Prop({ type: Date, required: true }) createdAt: Date; @Prop({ type: Date, required: true }) updatedAt: Date; }
解决方案
问题原因
Product的label字段定义为mongoose.Schema.Types.ObjectId,是对Label文档的引用关系,数据库中存储的只是Label的ID值,并非完整的Label对象。因此直接通过'label.name'查询时,数据库中不存在这个字段路径,自然返回空数组。
方法一:先查Label ID再查Product
先找到名称为'Something'的Label的ID,再用该ID查询关联的Product:
// 第一步:获取目标Label的ID const targetLabel = await this.labelModel.findOne({ name: 'Something' }); if (!targetLabel) { return []; } // 第二步:查询关联该Label的所有Product return this.productModel.find({ label: targetLabel._id });
方法二:使用聚合管道关联查询
通过MongoDB的聚合$lookup操作,关联Label集合后再筛选符合条件的记录:
return this.productModel.aggregate([ // 关联Label集合,将匹配的Label数据加入product文档 { $lookup: { from: 'labels', // 注意这里是Label集合的实际名称,通常为模型名小写复数 localField: 'label', foreignField: '_id', as: 'label' } }, // 展开label数组(因为$lookup返回的是数组) { $unwind: '$label' }, // 筛选label名称为'Something'的记录 { $match: { 'label.name': 'Something' } } ]);
内容的提问来源于stack exchange,提问作者nerrood
相关产品推荐
相关产品推荐

