例子:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
例子:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
当前回答
记住前面的例子:
db.stuff.find( { foo: /bar/i } );
将导致每个包含bar的条目匹配查询(bar1, barxyz, openbar),这可能是非常危险的用户名搜索认证功能…
您可能需要使用适当的regexp语法使其仅匹配搜索项,如下:
db.stuff.find( { foo: /^bar$/i } );
有关正则表达式的语法帮助,请参阅http://www.regular-expressions.info/
其他回答
更新:
原来的答案现在已经过时了。Mongodb现在支持高级全文搜索,有很多特性。
最初的回答:
需要注意的是,使用regex的大小写不敏感/i进行搜索意味着mongodb不能通过索引进行搜索,因此针对大型数据集的查询可能需要很长时间。
即使数据集很小,效率也不是很高。cpu消耗比查询所保证的要大得多,如果您试图实现规模化,这可能会成为一个问题。
作为一种替代方法,您可以存储一个大写的副本并根据它进行搜索。例如,我有一个用户表,其中有一个混合大小写的用户名,但id是用户名的大写副本。这确保了区分大小写的复制是不可能的(同时拥有“Foo”和“Foo”是不允许的),并且我可以通过id = username. touppercase()进行搜索,以获得对用户名不区分大小写的搜索。
如果字段很大,比如消息体,复制数据可能不是一个好选择。我相信在这种情况下,使用像Apache Lucene这样的无关索引器是最好的选择。
记住前面的例子:
db.stuff.find( { foo: /bar/i } );
将导致每个包含bar的条目匹配查询(bar1, barxyz, openbar),这可能是非常危险的用户名搜索认证功能…
您可能需要使用适当的regexp语法使其仅匹配搜索项,如下:
db.stuff.find( { foo: /^bar$/i } );
有关正则表达式的语法帮助,请参阅http://www.regular-expressions.info/
聚合框架在mongodb 2.2中引入。您可以使用字符串操作符"$strcasecmp"在字符串之间进行不区分大小写的比较。它比使用regex更值得推荐,也更简单。
下面是关于聚合命令操作符的官方文档:https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp。
我很惊讶没有人警告通过使用/^bar$/ I正则表达式注入的风险,如果bar是密码或帐户id搜索。例如,bar => .*@myhackeddomain.com,所以我的打赌是:使用\Q \E正则表达式特殊字符!PERL提供
db.stuff.find( { foo: /^\Qbar\E$/i } );
当bar = '\E *@myhackeddomain.com\Q'时,您应该使用\\字符转义bar变量,以避免再次被\E利用
另一种选择是使用一个regex转义字符策略,就像这里描述的Javascript等价于Perl的\Q…\E或quotemeta()
对于任何使用Golang并希望使用mongodb和mgo godoc globalsign库进行区分大小写的全文搜索的人。
collation := &mgo.Collation{
Locale: "en",
Strength: 2,
}
err := collection.Find(query).Collation(collation)