【问题标题】:How to compare string in MongoDB whether it is in lowercase or is in uppercase如何比较MongoDB中的字符串是小写还是大写
【发布时间】:2019-03-20 20:32:38
【问题描述】:

我正在做一个 MERN 项目,在用户登录时我发现这个用户是这样的:

User.findOne({username:req.body.username}).exec(function(err,user){ 如果(用户){ 代码行...... });

假设我的用户名是 Imran 保存在 Db 中,并在上述代码中将用户名发送为 .

案例1: req.body.username = 伊姆兰 找到用户 1

案例2: req.body.username = imran 找到用户 0

案例3: req.body.username = imRan 找到用户 0

如果我使用正则表达式来查找这样的用户名...

User.findOne({username: {$regex: username , $options : "i"}})

它会在上述所有情况下找到用户,但如果我输入 imr 而不是 Imran 或 imran 或 imRan 并给出密码,它将再次登录该用户,这是不正确的!所以我很希望。如果有人可以帮助我解决这个问题!那会很棒!

【问题讨论】:

  • 您能解释一下您希望对用户名字段做什么吗? AFAIK,mongodb 只会为案例 1 验证您的用户名,这应该是唯一的案例。如果您打算执行自动完成或任何其他操作,那么最好在顶层而不是您的数据库中完成它,以尽量减少您对性能的负担。

标签: node.js regex mongodb express mongodb-query


【解决方案1】:

您可能希望在保存数据时通过调用username.toLowerCase()(或toUpperCase())对其进行规范化。然后,当你执行查询时,你会调用User.findOne({username:req.body.username.toLowerCase()})

【讨论】:

  • 我支持这个建议。不清理用户输入并将它们直接存储在数据库中通常是不好的做法。除非您打算允许混合大小写的用户名,否则您应该清理您的输入。
  • 我不完全同意。如果外壳真的很重要怎么办?喜欢名字吗?为什么要保存小写数据?
  • @JuanManuelHaedo 如果大小写不重要,您肯定只想以这种方式规范化数据。例如,电子邮件地址不区分大小写。对于区分大小写的字段,您需要使用不区分大小写的 $regex 搜索,或者您可能有一个重复的字段,该字段被标准化为所有小写以进行不区分大小写的搜索。
【解决方案2】:

我建议存储小写用户名,至少您想区分小写和大写用户名,如果这种情况,Imranimran 是两个不同的用户。无论哪种方式,要匹配不区分大小写的查询,您都可以尝试以下操作:

User.findOne({username: /^imran$/i})

或者

User.findOne({username: {$regex: '^imran$', $options: 'i'}})

在最后一个中,您将正则表达式值作为字符串传递,因此您可以在^$ 之间包含一个变量,希望对您有所帮助。

【讨论】:

  • 我怎样才能给出除 Imran 之外的动态值!我正在这样做.. User.findOne( {username: /^username$/I } )... 但不工作
  • 试试:User.findOne({username: {$regex: '^imran$', $options: 'i'}}),我会编辑
  • 你可以使用变量User.findOne({username: {$regex: new RegExp(`^${username}$`, 'i')}})使其动态化
  • 请注意,imran.munawar@gmail.comimranamunawar@gmail.com 在使用 \b\b 或 ^$ 时匹配,因为点被解释为任何字符串。
【解决方案3】:

感谢大家的帮助!我找到了适合我的解决方案。 User.findOne( { username: new RegExp("\b" + username + "\b" , "i" ) } .... 这将匹配用户名字符串,无论它是小写还是大写。希望对你有帮助:)

【讨论】:

  • 根据我上面的评论,出于同样的原因,这不起作用(字符串中的正则表达式会干扰)。
【解决方案4】:

在我的用例(电子邮件)中,我遇到了问题,因为其他答案会匹配未转义的数据。

例如,当使用非转义字符串时,.电子邮件中的(点字符)将用于匹配任何字符,因此 imran.munawar@gmail.comimranamunawar@gmail.com 在搜索 imran.munawar@gmail.com 时都会匹配。

我对此的解决方案是先转义字符串。我还建议清理您的输入,但如果您不能,请确保您转义您的字符串。

    if (email) {
        email = _.escapeRegExp(email.toLowerCase());
        let filter = { email: { $regex: new RegExp(`^${email}$`, 'i') } };
    }

上述解决方案需要lodash,但可以使用字符串替换方法来代替。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-21
    • 2011-09-15
    • 2012-01-03
    • 1970-01-01
    • 2012-11-12
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多