当前位置:  开发笔记 > 编程语言 > 正文

如何在Mongodb上进行不区分大小写的查询?

如何解决《如何在Mongodb上进行不区分大小写的查询?》经验,为你挑选了6个好方法。

Chris Fulstow的解决方案将起作用(+1),但是,它可能效率不高,特别是如果你的收藏非常大.非root的正则表达式(那些不是以正则表达式开头^,将正则表达式锚定到字符串的开头),以及那些使用i不区分大小写的标志的表达式将不使用索引,即使它们存在.

您可能考虑的另一种选择是对数据进行非规范化以存储name字段的小写版本,例如name_lower.然后,您可以有效地查询(特别是如果它被索引)对不区分大小写的完全匹配,例如:

db.collection.find({"name_lower": thename.toLowerCase()})

或者使用前缀匹配(带根的正则表达式):

db.collection.find( {"name_lower":
    { $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);

这两个查询都将使用索引name_lower.



1> dcrosta..:

Chris Fulstow的解决方案将起作用(+1),但是,它可能效率不高,特别是如果你的收藏非常大.非root的正则表达式(那些不是以正则表达式开头^,将正则表达式锚定到字符串的开头),以及那些使用i不区分大小写的标志的表达式将不使用索引,即使它们存在.

您可能考虑的另一种选择是对数据进行非规范化以存储name字段的小写版本,例如name_lower.然后,您可以有效地查询(特别是如果它被索引)对不区分大小写的完全匹配,例如:

db.collection.find({"name_lower": thename.toLowerCase()})

或者使用前缀匹配(带根的正则表达式):

db.collection.find( {"name_lower":
    { $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);

这两个查询都将使用索引name_lower.


这实际上并不完全正确,因为在寻找"安德鲁"时你可能会找到"安德鲁的东西".因此,将正则表达式调整为:`new RegExp('^'+ username +'$',"i")`是完全匹配.
根据MongoDB网站,任何不区分大小写的正则表达式都不具有索引效率"当正则表达式具有字符串开头(即^)的锚点时,$ regex只能有效地使用索引,并且是**区分大小写的匹配**"
使用Mongoose可以为我工作:User.find({'username':{$ regex:new RegExp('^'+ username.toLowerCase(),'i')}},function(err,res){if(err )throw err; next(null,res);});
在使用正则表达式时,永远不要忘记逃避名称.我们不希望注射接管mongodb的美丽.想象一下,您将此代码用于登录页面,用户名为".*.".

2> Chris Fulsto..:

你需要对这个使用不区分大小写的正则表达式,例如

db.collection.find( { "name" : { $regex : /Andrew/i } } );

要使用thename变量中的正则表达式模式,请构造一个新的RegExp对象:

var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );

更新:要完全匹配,您应该使用正则表达式"name": /^Andrew$/i.感谢Yannick L.


@JonathanCremin帮助别人你应该发布正确答案:`{"name":/ ^ Andrew $/i}`
你知道如何使用Node.js mongoose做到这一点吗?
这是错误的,它会匹配任何文件_containing_"andrew"为`name`,而不仅仅是等于.

3> RIPAN..:

我已经解决了这个问题.

 var thename = 'Andrew';
 db.collection.find({'name': {'$regex': thename,$options:'i'}});

如果你想查询'不区分大小写的完全匹配'那么你可以这样做.

var thename =  '^Andrew$';
db.collection.find({'name': {'$regex': thename,$options:'i'}});



4> user3413723..:

MongoDB 3.4现在包含创建真实的不区分大小写索引的功能,这将大大提高大型数据集上不区分大小写的查询的速度。通过指定强度为2的排序规则来完成。

可能最简单的方法是在数据库上设置排序规则。然后所有查询都继承该排序规则并将使用它:

db.createCollection("cities", { collation: { locale: 'en_US', strength: 2 } } )
db.names.createIndex( { city: 1 } ) // inherits the default collation

您也可以这样:

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

并像这样使用它:

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

这将返回名为“纽约”,“纽约”,“纽约”等的城市。

有关更多信息:https : //jira.mongodb.org/browse/SERVER-90



5> Raymond Gan..:

    与猫鼬(和节点),这工作:

    User.find({ email: /^name@company.com$/i })

    User.find({ email: new RegExp(`^ $ {emailVariable} $`,'i')})

    在MongoDB中,这有效:

    db.users.find({ email: { $regex: /^name@company.com$/i }})

这两行都不区分大小写。数据库中的电子邮件可能是NaMe@CompanY.Com,这两行仍将在数据库中找到对象。

同样,我们可以使用/^NaMe@CompanY.Com$/i并且它仍然可以name@company.com在数据库中找到电子邮件:。



6> 小智..:

几个小时前我刚刚解决了这个问题.

var thename = 'Andrew'
db.collection.find({ $text: { $search: thename } });

在以这种方式进行查询时,默认情况下,区分大小写和变音符敏感性设置为false.

您甚至可以通过以下方式选择Andrew的用户对象所需的字段来扩展此功能:

db.collection.find({ $text: { $search: thename } }).select('age height weight');

参考:https://docs.mongodb.org/manual/reference/operator/query/text/#text

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有