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

Cha*_*ory 7 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();
};
Run Code Online (Sandbox Code Playgroud)

Sum*_*eet 16

你可以使用正则表达式.

var isAlreadyRegistered = Profiles.findOne({"username": /^newName$/i });
Run Code Online (Sandbox Code Playgroud)

或者您也可以这样查询:

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


Nei*_*unn 5

有两种方法,您的里程可能因最适合您的方法而异,但实际上这两种方法都相当可怕,因为 MongoDB 进行“区分大小写”匹配:

第一种方法是使用$regex

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

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

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

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

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

这里的问题是这将$project超过管道中的所有内容。但是如果你可以的话,它会很有用$match

当然,我认为这aggregate仅在服务器端可用,而不能通过 Minimongo,因此需要考虑。