例子:
> 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
当前回答
最好的方法是在你选择的语言中,当为你的对象创建模型包装器时,让你的save()方法遍历一组你将搜索的字段,这些字段也被索引了;这组字段应该有对应的小写字母,然后用于搜索。
每次再次保存对象时,都会检查小写属性并更新主属性的任何更改。这将使您可以有效地搜索,但隐藏了每次更新lc字段所需的额外工作。
小写字段可以是一个键值对象存储,或者只是字段名加上前缀lc_。我使用第二种方法来简化查询(深度对象查询有时会令人困惑)。
注意:您希望索引lc_字段,而不是它们所基于的主字段。
其他回答
最好的方法是在你选择的语言中,当为你的对象创建模型包装器时,让你的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();
我也遇到过类似的问题,这对我很有帮助:
const flavorExists = await Flavors.findOne({
'flavor.name': { $regex: flavorName, $options: 'i' },
});
你可以使用不区分大小写的索引:
下面的示例创建一个没有默认排序规则的集合,然后在名称字段上添加一个索引,排序规则不区分大小写。Unicode国际组件
/* strength: CollationStrength.Secondary
* Secondary level of comparison. Collation performs comparisons up to secondary * differences, such as diacritics. That is, collation performs comparisons of
* base characters (primary differences) and diacritics (secondary differences). * Differences between base characters takes precedence over secondary
* differences.
*/
db.users.createIndex( { name: 1 }, collation: { locale: 'tr', strength: 2 } } )
要使用索引,查询必须指定相同的排序规则。
db.users.insert( [ { name: "Oğuz" },
{ name: "oğuz" },
{ name: "OĞUZ" } ] )
// does not use index, finds one result
db.users.find( { name: "oğuz" } )
// uses the index, finds three results
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 2 } )
// does not use the index, finds three results (different strength)
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 1 } )
或者你可以创建一个默认排序规则的集合:
db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
记住前面的例子:
db.stuff.find( { foo: /bar/i } );
将导致每个包含bar的条目匹配查询(bar1, barxyz, openbar),这可能是非常危险的用户名搜索认证功能…
您可能需要使用适当的regexp语法使其仅匹配搜索项,如下:
db.stuff.find( { foo: /^bar$/i } );
有关正则表达式的语法帮助,请参阅http://www.regular-expressions.info/