Reputation: 4151
I have some documents as following in db:
User A:
{
"_id" : ObjectId("5f1ec1869ea3e213cc2a159e"),
"age": 27,
"gender": "male",
"preference": {
"ageGroup": "25-35",
"gender": "female"
}
}
User X:
{
"_id" : ObjectId("378ec1869ea3e212333a159e"),
"age": 27,
"gender": "female",
"preference": {
"ageGroup": "20-30",
"gender": "male"
}
}
I am trying to filter docs based on :
age
and gender
must match against the user's preference.age
and gender
.Here's what I am trying:
const getGsaMatches = async function (currentUser) {
const user: any = await User.findOne({ _id: currentUser._id });
const userPreference = user.preference;
const ageRange = userPreference.ageGroup.split("-");
const minAgeRange = ageRange[0];
const maxAgeRange = ageRange[1];
const matchResponse: any = await User.find({
"gender": userPreference.gender,
"age": { $gte: minAgeRange, $lte: maxAgeRange },
"preference.gender": user.gender,
"preference.ageGroup": user.age, // I'm stuck here
_id: { $ne: currentUser._id }
});
return matchResponse;
}
preference.ageGroup
contains value in 25-30
string format.
How can I store this field so that it can be compared against a given single integer
value?
I hope I made the problem clear.
Upvotes: 1
Views: 111
Reputation: 22296
A good way to start is to actually store it as an Integer. If you're using Mongo v4.0+ you can also use $toInt but if this is a query you're doing often then you might aswell save it in a structure like:
ageGroup: {
min: 20,
max: 30,
value: "20-30"
}
Now you can do something like this:
const matchResponse: any = await User.find({
_id: { $ne: currentUser._id },
"gender": userPreference.gender,
"age": { $gte: minAgeRange, $lte: maxAgeRange },
"preference.gender": user.gender,
"preference.ageGroup.min": {$lte: user.age},
"preference.ageGroup.max": {$gte: user.age}
});
Assuming you don't want to change the structure then you'll have to use an aggregation with $toInt
as I suggested like so:
const matchResponse: any = await User.aggregate([
{
$addFields: {
tmpAgeField: {
$map: {
input: {$split: ["$preference.ageGroup", "-"]},
as: "age",
in: {$toInt: "$$age"}
}
}
}
},
{
$match: {
_id: { $ne: currentUser._id },
"gender": userPreference.gender,
"age": { $gte: minAgeRange, $lte: maxAgeRange },
"preference.gender": user.gender,
"tmpAgeField.0": {$lte: user.age},
"tmpAgeField.1": {$gte: user.age}
}
}
]);
Upvotes: 1