【问题标题】:Express.js - Mongoose multiple or conditionsExpress.js - Mongoose 多个或条件
【发布时间】:2018-07-19 00:46:12
【问题描述】:

我有一个userSchema 我必须用搜索关键字在用户记录中搜索

//userSchema 
const userSchema = new Schema(
    {
        name: String,
        city: String,
        postalCode: Number
    },
    {
        timestamps: true
    }
);

所以 API 路由是localhost:3000/api/v1/search/:key 键可以是用户名或城市或邮政编码,根据我们必须从集合中获取结果的键。

这是我尝试过的userController

index: async (req, res, next) => {

    const searchKey = req.params.key;

    const searchResult = await User.find({
        $or:[{name: searchKey},{city: searchKey},{postalCode: searchKey}]
    });

    res.status(200).json({
        message: 'query was succesfull',
        data: searchResult
    });
}

如果我将 :key 传递为 加拿大,我会收到以下错误。如果我将 :key 传递为 123456 这是邮政编码,我正在获取数据

{
    "error": {
        "message": "Cast to number failed for value \"Canada\" at path \"postalCode\" for model \"users\""
    }
}

那么我如何使这个查询更加健壮,以便基于:key 我必须从用户模型中获取数据

寻找急需的帮助

谢谢。

【问题讨论】:

  • 快速修复尝试:{postalCode: Number(searchKey)}
  • @AndreiC 感谢您的回复,我尝试通过将 searchKey 作为字符串传递来搜索名称和城市时出现错误

标签: node.js mongodb api express mongoose


【解决方案1】:

因为在userSchema中你声明postalCode为数字类型,猫鼬期望searchKey为数字,尝试基于searchKey类型构建查询条件:

// if searchKey is number
if ( parseInt(searchKey) ) {
    var condition = { postalCode: searchKey };
} else {
    var condition = { $or:[ { name: searchKey }, { city: searchKey }] };
}

const searchResult = await User.find(condition);

编辑:如果您想按单词相似度搜索,请使用$regex 运算符,但首先您需要将postalCode 类型更改为字符串:

const searchResult = await User.find({
    $or:[ 
        { name: { $regex: new RegExp(searchKey, 'i') } },
        { city: { $regex: new RegExp(searchKey, 'i') } },
        { postalCode: { $regex: new RegExp(searchKey, 'i') } }
    ]
});

【讨论】:

  • 感谢您抽出宝贵时间,我真的很感激,我尝试了您的解决方案,它仅在我将 :key 作为整数传递但如果我想搜索 Name 和 城市我收到以下错误{ "error": { "message": "Cast to number failed for value \"NaN\" at path \"postalCode\" for model \"users\"" } }
  • 看起来猫鼬将NaN视为字符串,我更新我的答案请看一下
  • 完美!这行得通,但只需要一些输入,它是实现搜索查询的理想方式吗?如果我输入完整的代码 123123,那么只有我会得到结果是否有一个查询,我只输入 12 然后列出从 12 开始的所有邮政编码,或者只是 Ca 然后列出从 Ca开始的所有城市名称>
  • 如果您想按单词相似度搜索,我认为最好将 postalCode 类型更改为字符串并使用 $regex 运算符,我会更新我的答案
【解决方案2】:

试试:

{postalCode: isNaN(parseInt(searchKey)) ? undefined : parseInt(searchKey)}

【讨论】:

    猜你喜欢
    • 2021-04-29
    • 2018-03-11
    • 2014-02-12
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 2018-01-30
    相关资源
    最近更新 更多