提问者:小点点

nodejs mongodb根据单个值检查范围


我在数据库中有以下文件:

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值进行比较?

我希望我把问题说清楚了。


共1个答案

匿名用户

一个好的开始方法是将它实际存储为整数。 如果您使用的是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}
        }
    }
]);