'How to $match a field conditionally in mongo DB
I have the following schema:
User: {
...otherFields,
isDumb: false,
type: "A" // could be "A", "B", or "C"
}
I want to fetch all dumb users by default and fetch by type only if the type is passed through the parameters.
static async getUsers(req: any, res: Response) {
const { type = "" } = req.params;
const queryPipeline = [
{
$match: {
isDumb: true,
type: // I want to only filter by type if the param is passed in
}
}
]
const users = await User.aggregate(queryPipeline);
So if my data was:
[
{
...otherFields,
isDumb: false,
type: "A"
},
{
...otherFields,
isDumb: true,
type: "B"
},
{
...otherFields,
isDumb: true,
type: "C"
}
]
and req.params.type was "B", I should get back:
[
{
...otherFields,
isDumb: true,
type: "B"
}
],
if req.params.type was undefined, I should get all dumb users
[
{
...otherFields,
isDumb: true,
type: "B"
},
{
...otherFields,
isDumb: true,
type: "C"
}
]
Solution 1:[1]
you just have to build an object and pass it to match
const matchParams = req.params.type ? {isDumb:true,type:req.params.type } : {isDumb:true }
Solution 2:[2]
You can create the object using JS:
const params = "A" // get req.params as you want
let query = {$match:{isDumb:true}}
if(params) query.$match.type = params
console.log(query)
Solution 3:[3]
First, you don't need to use Aggregation Framework for simple find query. You can use find method instead.
Second, consider approach where you initialize the filter with isDumb: true, and add new type property only if req.params.type exists.
let filter = { isDumb: true };
if(req.params.type) filter.type = req.params.type;
const users = await User.find(filter);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | K1games |
| Solution 2 | J.F. |
| Solution 3 | NeNaD |
