我在数据库中有以下文件:
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"
}
}
我尝试基于以下条件筛选文档:
年龄
和性别
必须与用户的首选项匹配。年龄
和性别
相匹配。下面是我正在尝试的:
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
包含25-30
字符串格式的值。
如何存储此字段,以便与给定的单个integer
值进行比较?
我希望我把问题说清楚了。
一个好的开始方法是将它实际存储为整数。 如果您使用的是MongoV4.0+,您也可以使用$toInt,但如果这是您经常执行的查询,那么您也可以将其保存为如下结构:
ageGroup: {
min: 20,
max: 30,
value: "20-30"
}
现在您可以做如下操作:
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}
});
假设您不想更改结构,那么您必须使用带有$toInt
的聚合,就像我建议的那样:
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}
}
}
]);