BigDaddy
BigDaddy

Reputation: 39

mongoose invalid operator $match

I am going to handle users search based on email_address, firstname, lastname, type and phone_number.

phone_number search will be exact search with & without country code while others will be containing & case-insensitive search.

So, I wrote the below code.

User.aggregate(
    [
        {
            "$redact": {
                "$cond": [
                    {
                        "$and": [
                            { 
                                "$match": {
                                    type: req.body.type,
                                    email_address: new RegExp((req.body.email_address || req.body.any || '').toLowerCase(), "i"),
                                    "firstname": new RegExp((req.body.firstname || req.body.any || '').toLowerCase(), "i") ,
                                    "lastname": new RegExp((req.body.lastname || req.body.any || '').toLowerCase(), "i") 
                                }
                            },
                            {
                                "$or": [
                                    {
                                        "$setIsSubset": [
                                            [
                                                { "$substr": [ "$phone_number.local_number", 0, -1 ] }
                                            ],
                                            [req.body.phone_number, req.body.any]
                                        ]
                                    },
                                    {
                                        "$setIsSubset": [
                                            [
                                                { 
                                                    "$concat": [ 
                                                        { "$substr": [ "$phone_number.country_code", 0, -1 ] },
                                                        { "$substr": [ "$phone_number.local_number", 0, -1 ] }
                                                    ] 
                                                }
                                            ],
                                            [req.body.phone_number, req.body.any]
                                        ]
                                    }, 
                                    {}            
                                ]

                            }
                        ]

                    },
                    "$$KEEP",
                    "$$PRUNE"
                ]
            }
        }
    ],
    function(err, users) {
        if (err) {
            return res.json({ success: false, err: err });
        }
        res.json({ success: true, users: users });
    }
);

But when I run this code, I get "invalid operator '$match'" error.

If I remove $match, it evaluate req.body values as expression instead of value and emit "FieldPath 'abc' doesn't start with $" kind error.

So, I hope to get help how to solve this problem and search by conditions.

Please help me !!!

Upvotes: 1

Views: 449

Answers (1)

chridam
chridam

Reputation: 103475

Move the $match outside $redact as it's an independent pipeline stage, it will provide the initial filter with the regex that can otherwise be invalid within the $redact pipeline:

User.aggregate([
    { 
        "$match": {
            "type": req.body.type,
            "email_address": new RegExp((req.body.email_address || req.body.any || '').toLowerCase(), "i"),
            "firstname": new RegExp((req.body.firstname || req.body.any || '').toLowerCase(), "i") ,
            "lastname": new RegExp((req.body.lastname || req.body.any || '').toLowerCase(), "i") 
        }
    },
    {
        "$redact": {
            "$cond": [
                {
                    "$or": [
                        {
                            "$setIsSubset": [
                                [ { "$substr": [ "$phone_number.local_number", 0, -1 ] } ],
                                [req.body.phone_number, req.body.any]
                            ]
                        },
                        {
                            "$setIsSubset": [
                                [
                                    { 
                                        "$concat": [ 
                                            { "$substr": [ "$phone_number.country_code", 0, -1 ] },
                                            { "$substr": [ "$phone_number.local_number", 0, -1 ] }
                                        ] 
                                    }
                                ],
                                [req.body.phone_number, req.body.any]
                            ]
                        }            
                    ]

                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
], function(err, users) {
        if (err) {
            return res.json({ success: false, err: err });
        }
        res.json({ success: true, users: users });
    }
);

Upvotes: 1

Related Questions