Home > database >  Quering by nested object in mongoose and nestjs
Quering by nested object in mongoose and nestjs

Time:11-08

I Label document which is nested inside Product document.

Now i trying to find all documents where Label has some name but instead of array of objects this array is empty.

What im using to get docs

return this.productModel.find({
      'label.name': 'Something',
    });

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;
}

CodePudding user response:

This is because your label is an ObjectId while on the product model, so you can only query it by ObjectId. There are a few ways to solve this. The most ideal would be to look up by ObjectId directly instead of by name (e.g. if this is coming from the client, and they are selecting the label, have the client send the labels id, not the labels name).

If that isn't possible, I'd recommend first looking up the label.

const label = await labelModel.findOne({name: 'Something'}, {_id: 1})
const products = await productModel.find({label: label._id})
  • Related