Node.js nodejs mongodb根据单个值检查范围

Node.js nodejs mongodb根据单个值检查范围,node.js,mongodb,nosql,Node.js,Mongodb,Nosql,我在db中有以下文件: User A: { "_id" : ObjectId("5f1ec1869ea3e213cc2a159e"), "age": 27, "gender": "male", "preference": { "ageGroup": "25-35", &quo

我在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"
    }
}
我正在尝试根据以下内容筛选文档:

  • 其他用户的个人资料
    年龄
    性别
    必须与用户的偏好相匹配
  • 其他用户的偏好也必须与用户的个人资料
    年龄
    性别
    相匹配
以下是我正在尝试的:

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
字符串格式的值

如何存储此字段,以便将其与给定的单个
整数值进行比较


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

一个好的开始方法是将它实际存储为整数。如果您使用的是Mongo v4.0+,您也可以使用,但如果这是您经常使用的查询,那么您也可以将其保存在如下结构中:

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}
        }
    }
]);

你会建议哪种方法?如果重新提取数据不太困难,那么我建议你这样做,最终如果它不让你去处理字符串结构,那就太糟糕了,但是像这样的查询总是很困难,你永远无法使用索引来支持它。谢谢。我会重新构建它。。顺便问一下,为什么
ageGroup.value
?有什么目的吗?没有,我只是保留了原来的结构,以防你在其他地方使用它,但你可以直接放下它