How can I filter data based on populated fields

Viewed 45

Product Schema

const ProductSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      trim: true,
      required: [true, "Please provide product name"],
      maxlength: [100, "Product name cannot be more than 100 characters"],
      minlength: [5, "Product name cannot be less than 10 characters"],
    },
    description: {
      type: String,
      required: [true, "Please provide product description"],
      maxlength: [
        1000,
        "Product description cannot be more than 1000 characters",
      ],
    },
    price: {
      type: Number,
      required: [true, "Please provide product price"],
      min: [100, "Minimum price of a product cannot be less than 100"],
    },
    discountPercentage: {
      type: Number,
      default: 0,
      min: [
        0,
        "You cannot provide discount percentage of a product less than 0.",
      ],
    },
    category: {
        type: mongoose.Schema.ObjectId,
        ref: "Category",
    },
    brand: {
        type: mongoose.Schema.ObjectId,
        ref: "Brand",
    },
    stock: {
      type: Number,
      required: false,
      default: 15,
    },
    rating: {
      type: Number,
      default: 4.5,
      min: [1, "Rating must be above 1.0"],
      max: [5, "Rating must be below 5.0"],
      set: (value) => Math.round(value * 10) / 10,
    },
    numberOfReviews: {
      type: Number,
      default: 0,
    },
    thumbnail: {
      type: String,
      required: [true, "Please provide thumbnail for your product"],
    },
    images: {
      type: [String],
      required: false,
    },
    seller: {
        type: mongoose.Schema.ObjectId,
        ref: "User",
    },
    active: {
      type: Boolean,
      default: true,
    },
    slug: {
      type: String,
      default: function () {
        return slugify(this.name, { lower: true });
      },
    },
  },
  {
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
  }
);

Document without populated fields

{
  "discountPercentage": 5.92,
  "category": "5c8a38c714eb5c17645c911b",
  "brand": "5c8a3abc14eb5c17645c9128",
  "stock": 44,
  "rating": 5,
  "numberOfReviews": 0,
  "images": [
    "https://dummyjson.com/image/i/products/98/1.jpg",
    "https://dummyjson.com/image/i/products/98/2.jpg",
    "https://dummyjson.com/image/i/products/98/3.jpg",
    "https://dummyjson.com/image/i/products/98/4.jpg",
    "https://dummyjson.com/image/i/products/98/thumbnail.jpg"
  ],
  "seller": 62dd1a1ace415b229452393e",
  "active": true,
  "_id": "62e2d0324971c94a30715b44",
  "name": "3 lights lndenpant kitchen islang",
  "description": "3 lights lndenpant kitchen islang dining room pendant rice paper chandelier contemporary led pendant light modern chandelier",
  "price": 34,
  "thumbnail": "https://dummyjson.com/image/i/products/98/thumbnail.jpg",
  "slug": "3-lights-lndenpant-kitchen-islang",
  "createdAt": "2022-07-28T18:06:43.006Z",
  "updatedAt": "2022-07-28T18:06:43.006Z",
  "discountedPrice": 32,
  "id": "62e2d0324971c94a30715b44"
},

Document with populated fields (brand and category)

{
  "discountPercentage": 5.92,
  "category": {
    "_id": "5c8a38c714eb5c17645c911b",
    "name": "lighting",
    "slug": "lighting"
  },
  "brand": {
    "_id": "5c8a3abc14eb5c17645c9128",
    "name": "dadawu",
    "slug": "dadawu"
  },
  "stock": 44,
  "rating": 5,
  "numberOfReviews": 0,
  "images": [
    "https://dummyjson.com/image/i/products/98/1.jpg",
    "https://dummyjson.com/image/i/products/98/2.jpg",
    "https://dummyjson.com/image/i/products/98/3.jpg",
    "https://dummyjson.com/image/i/products/98/4.jpg",
    "https://dummyjson.com/image/i/products/98/thumbnail.jpg"
  ],
  "seller": "62dd1a1ace415b229452393e",
  "active": true,
  "_id": "62e2d0324971c94a30715b44",
  "name": "3 lights lndenpant kitchen islang",
  "description": "3 lights lndenpant kitchen islang dining room pendant rice paper chandelier contemporary led pendant light modern chandelier",
  "price": 34,
  "thumbnail": "https://dummyjson.com/image/i/products/98/thumbnail.jpg",
  "slug": "3-lights-lndenpant-kitchen-islang",
  "createdAt": "2022-07-28T18:06:43.006Z",
  "updatedAt": "2022-07-28T18:06:43.006Z",
  "discountedPrice": 32,
  "id": "62e2d0324971c94a30715b44"
},

I'm using a middleware to populate all fields whenever a request is made to an API

ProductSchema.pre(/^find/, function (next) {
  this.populate({
    path: "category",
    select: "name _id slug",
  }).populate({
    path: "brand",
    select: "name _id slug -categories",
  });
  next();
});

My question is that how can I filter the data based on populated fields.

For example: If I want to filter data based on category and brand, /products?catergory=smartphones&brand=apple

How to fulfill the above condition?

Mongoose version: ^5.13.14

0 Answers
Related