So I have a mongo schema, which looks something like this:
const UserSchema = new mongoose.Schema({
profile: {
// ...other stuff
age: {
type: Number,
min: [18, "Min age is 18"],
max: [99, "Max age is 99"],
},
And Im trying to query it through postman with the following: /users?profile.age[lte]=100
Other queries work, such as users?profile.age=36
. This returns the correct number of results, as does users?profile.age[eq]=36
. They both return the correct number of results.
In my controller I have:
export const getUsers = asyncHandler(async (req, res, next) => {
let query;
let queryStr = JSON.stringify(req.query);
queryStr = queryStr.replace(
/b(gt|gte|lt|lte|in|elemMatch|eq)b/g,
(match) => `$${match}`
);
query = JSON.parse(queryStr);
const users = await User.find(query);
if (!users) {
next(new ErrorResponse(`Unable to get users.`, 500));
} else {
res.status(200).json({
success: true,
count: users.length,
data: users,
});
}
});
logging the query here gives me { 'profile.age': { '$lte': '36' } }
which looks right to me
So basically every time I use lt
lte
gt
gte
it just throws this error in my face:
CastError: Cast to Number failed for value "{ '$lte': '36' }" (type Object) at path "profile.age" for model "User"
Any help much appreciated.
Thanks!
Edit: I also tried query-to-mongo
in case I was handling the query incorrectly but it returns the same error.
Edit 2: Even just this:
const users = await User.find({
"profile.age": { $lte: 100 },
});
Returns the error
3
Answers
So I got it working like this:
I'm not sure why
User.aggregate
works andUser.find()
doesn't work, but this seems to work in the exact same way.I was also facing the same problem. Mongoose cannot filter numeric string. So I came up with this idea. The below function checks upto 2 level.
Hope this would work for you
If you have
sanitizeFilter
set totrue
, set it back tofalse
may solve this problem.