例子:

> db.stuff.save({"foo":"bar"});

> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0

当前回答

搜索变量并转义:

const escapeStringRegexp = require('escape-string-regexp')
const name = 'foo'
db.stuff.find({name: new RegExp('^' + escapeStringRegexp(name) + '$', 'i')})   

转义变量可以保护查询不受'攻击。*'或其他正则表达式。

escape-string-regexp

其他回答

最好的方法是在你选择的语言中,当为你的对象创建模型包装器时,让你的save()方法遍历一组你将搜索的字段,这些字段也被索引了;这组字段应该有对应的小写字母,然后用于搜索。

每次再次保存对象时,都会检查小写属性并更新主属性的任何更改。这将使您可以有效地搜索,但隐藏了每次更新lc字段所需的额外工作。

小写字段可以是一个键值对象存储,或者只是字段名加上前缀lc_。我使用第二种方法来简化查询(深度对象查询有时会令人困惑)。

注意:您希望索引lc_字段,而不是它们所基于的主字段。

我为不区分大小写的正则表达式创建了一个简单的Func,我在过滤器中使用它。

private Func<string, BsonRegularExpression> CaseInsensitiveCompare = (field) => 
            BsonRegularExpression.Create(new Regex(field, RegexOptions.IgnoreCase));

然后,只需按如下方式筛选一个字段。

db.stuff.find({"foo": CaseInsensitiveCompare("bar")}).count();

从MongoDB 3.4开始,执行快速不区分大小写搜索的推荐方法是使用不区分大小写索引。

我亲自给其中一位创始人发了邮件,请他把这个工作做好,他做到了!自2009年以来,JIRA上就有这个问题,许多人都要求提供这个功能。下面是它的工作原理:

通过指定强度为1或2的排序规则,可以创建不区分大小写的索引。你可以像这样创建一个不区分大小写的索引:

db.cities.createIndex(
  { city: 1 },
  { 
    collation: {
      locale: 'en',
      strength: 2
    }
  }
);

你也可以在创建集合时指定一个默认的排序规则:

db.createCollection('cities', { collation: { locale: 'en', strength: 2 } } );

在这两种情况下,为了使用不区分大小写的索引,你需要在find操作中指定与创建索引或集合时使用的相同的排序规则:

db.cities.find(
  { city: 'new york' }
).collation(
  { locale: 'en', strength: 2 }
);

这将返回"New York", "New York", "New York"等。

其他的笔记

The answers suggesting to use full-text search are wrong in this case (and potentially dangerous). The question was about making a case-insensitive query, e.g. username: 'bill' matching BILL or Bill, not a full-text search query, which would also match stemmed words of bill, such as Bills, billed etc. The answers suggesting to use regular expressions are slow, because even with indexes, the documentation states: "Case insensitive regular expression queries generally cannot use indexes effectively. The $regex implementation is not collation-aware and is unable to utilize case-insensitive indexes." $regex answers also run the risk of user input injection.

这些已经用于字符串搜索进行了测试

{'_id': /.*CM.*/}               ||find _id where _id contains   ->CM
{'_id': /^CM/}                  ||find _id where _id starts     ->CM
{'_id': /CM$/}                  ||find _id where _id ends       ->CM

{'_id': /.*UcM075237.*/i}       ||find _id where _id contains   ->UcM075237, ignore upper/lower case
{'_id': /^UcM075237/i}          ||find _id where _id starts     ->UcM075237, ignore upper/lower case
{'_id': /UcM075237$/i}          ||find _id where _id ends       ->UcM075237, ignore upper/lower case

如果你正在使用MongoDB Compass:

转到筛选器类型的集合-> {Fieldname: /string/i}

对于使用Mongoose的Node.js:

模型。find({FieldName: {$regex: "stringToSearch", $options: "i"}})