I have a service that displays products. I need to be able to search products by their fields (product name, barcode or sku).
Previously I used this approach
const query: FilterQuery<TProductSchema> = {};
if (search) {
query.$or = [
{
productName: {
$regex: String(search).split(' ').join('|'),
$options: 'i',
},
},
{
barcode: {
$regex: String(search),
$options: 'i',
},
},
{ sku: { $regex: String(search).split(' ').join('|'), $options: 'i' } },
];
}
if (folderId && folderId !== 'all') {
query.folder = { _id: folderId };
}
const products = await ProductModel.find<HydratedDocument<TProductSchema>>(query)
.limit(Number(limit) === -1 ? 0 : Number(limit))
.skip(Number(page) * Number(limit));
and it worked well but now I also need to include all documents count (which changes depending on selected folderId
) in the resulting object.
I thought I could do it with the aggregation framework but I can't figure out how to conditionally match documents only if search
is presented.
I thought I could do something like that
const products = await ProductModel.aggregate([
{ $match: {/* match folder */ },
{ /* count matched documents */ },
// next search documents IF `search` is present
{
$match: {
$cond: [search, /* here goes `query` object, '']
}
},
]);
but it doesn't work saying unknown top level operator "$cond"
So how can I apply $match
conditionally?
CodePudding user response:
You have created query in first code and you need to pass same in $match
it should work same.
$match: query