Reputation: 39
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
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