I have built a clothing store backend based on Express and Mongodb, In which there is one api which is used to filter and search. In this API we cannot filter based on multiple colors or size. the endpoint would be /products?color=green,blue&page=1&size=26,28
…. How to achieve this functionality?
const getAllProducts = async (req: Request, res: Response) => {
const { page, limit, search, color, size, category, brand } = req?.query;
let currentPage = Number(page) || 0;
let docLimit = Number(limit) || 10;
let searchDoc = search || '';
try {
const products = await Product.aggregate([
{
$lookup: {
from: 'stores',
localField: 'store',
foreignField: '_id',
as: 'store',
},
},
{
$match: {
$or: [
{
title: { $regex: searchDoc, $options: 'i' },
},
{
'store.name': { $regex: searchDoc, $options: 'i' },
},
],
...(color ? { color: { $regex: color, $options: 'i' } } : {}),
...(brand ? { 'store.name': { $regex: brand, $options: 'i' } } : {}),
...(size
? {
size: {
$in: [Number(size)],
},
}
: {}),
...(category ? { $expr: { $eq: ['$category', category] } } : {}),
},
},
{
$skip: currentPage * docLimit,
},
{
$limit: docLimit,
},
]);
const total = await Product.find().countDocuments();
const data = {
products,
total,
};
res.status(200).json({
statusCode: 200,
success: true,
message: 'fetch successfully',
data,
});
} catch (error) {
if (error instanceof Error) {
res.status(500).json({
statusCode: 500,
success: false,
message: error.message,
error,
});
}
}
};
Product Schema
const productSchema = new mongoose.Schema<IProduct>(
{
title: {
type: String,
required: true,
},
description: {
type: String,
},
color: {
type: [String],
required: true,
enum: [
'black',
'white',
'blue',
'brown',
'copper',
'gold',
'green',
'grey',
'navy',
'pink',
'orange',
],
},
price: {
type: Number,
required: true,
},
discount: {
type: Number,
default: 0,
},
rating: {
type: Number,
default: 0,
},
category: {
type: String,
enum: [
'shirts',
'jeans',
'jacket',
'top',
'skirts',
'pants',
'dresses',
't-shirts',
'hats',
'socks',
],
},
store: {
type: mongoose.Schema.Types.ObjectId,
ref: 'stores',
},
size: {
type: [Number],
},
quantity: {
type: Number,
default:5
},
productImg: [
{
src: {
type: String,
},
},
],
},
{ timestamps: true }
);
I am expecting to get products based on the provided colors or sizez.
2
Answers
I think you can
.split()
the color and size and use$in
operator to match colors or sizes.This code might not work if you copy and paste cuz I haven’t run it. But looking at it, it should imo.
Hope this helps you