Meteor:如何做一个不区分大小写的collection.findOne()?

时间:2014-04-12 08:21:42

标签: mongodb meteor

我正在为用户在我正在编写的Meteor应用程序中实现更改用户名的方法。在接受更改之前,我想检查用户名是否已存在。用户名可以包含大写和小写,但无论大小写,它们都必须是唯一的名称。例如,bobBob不能一起存在。

问题是我似乎无法弄清楚如何做一个不区分大小写的collection.findOne()。例如,假设我有一个名为Profiles的集合,我希望能够做到这样的事情:

newName = "bob";

//Assume "Bob" exists as a username in the Profiles collection;

var isAlreadyRegistered = Profiles.findOne({"username": newName});

if (isAlreadyRegistered == null) {
  saveUsername();
};

3 个答案:

答案 0 :(得分:15)

您可以使用regular expression.

var isAlreadyRegistered = Profiles.findOne({"username": /^newName$/i });

或者您也可以这样查询:

 var isAlreadyRegistered = Profiles.findOne({ "username" : {
                     $regex : new RegExp(newName, "i") } }
               );

答案 1 :(得分:2)

有两种方法,你的里程数可能会因你最好的方法而有所不同,但实际上两者都相当可怕,因为MongoDB确实存在这种情况,而且敏感的情况很严重。匹配:

第一种方法是使用$regex

Profiles.findOne({ "username": { 
    "$regex": "^" + newName + "\\b", "$options": "i"
}})

以不区分大小写的方式匹配单词并且只匹配字符串开头的确切单词。这里的问题是您正在扫描索引。

第二种方法是使用聚合进行投影:

db.collection("profiles").aggregate([
    { "$project": {
        "username": 1,
        "lower": { "$toLower": "$username" }
    }},
    { "$match": {
        "username": newName
    }}
])

你这样做的当然newName已经转换为小写。

这里的问题是 $project 会对管道中的所有内容产生影响。但如果您可能先 $match ,则会很有用。

当然我认为 aggregate 仅在服务器端提供,而不是通过Minimongo提供,因此需要考虑。

答案 2 :(得分:1)

作为您的基础用例的解决方案,我建议使用两个字段来存储用户名而不是一个。

内置用户名字段应存储用户名的小写版本。另一个额外字段存储原始区分大小写的版本。

将根据用户名'进行搜索。搜索条件的字段在使用前也会小写。

相关问题