当前位置: 首页 > 科技观察

3分钟掌握MongoDB中正则表达式的几种用法

时间:2023-03-12 02:48:51 科技观察

背景Part1:刚开始使用MySQL或者其他关系型数据库的朋友都知道,模糊查询的用法类似于:SELECT*FROMproductsWHEREskulike"%789";在这篇文章中介绍的MongoDB中的regex实现了类似的功能。Regex使您能够在查询中使用正则表达式。本文将通过简单的例子向大家展示MongoDB中regex的用法~Part2:用法在使用$regex时,有以下几种用法:{:{$regex:/pattern/,$options:''}}{:{$regex:'pattern',$options:''}}{:{$regex:/pattern/}}option参数的含义:选项的含义是使用Requiresicaseinsensitivem查询匹配使用锚点,比如^(代表开始)和$(代表结束),匹配\n之后的字符串x忽略所有空白字符需要$regex为与$option组合使用允许点字符(.)匹配所有字符,包括换行符。要求$regex与$option结合使用实战Part1:$in中的用法要在$in查询中包含正则表达式,只能使用JavaScript正则表达式对象(即/pattern/)。例如:{name:{$in:[/^acme/i,/^ack/]}}警告:警告$regex运算符表达式不能在$in中使用。第2部分:隐式和用法要在逗号分隔的查询条件中包含正则表达式,请使用$regex运算符。例如:{name:{$regex:/acme.*corp/i,$nin:['acmeblahcorp']}}{name:{$regex:/acme.*corp/,$options:'i',$nin:['acmeblahcorp']}}{name:{$regex:'acme.*corp',$options:'i',$nin:['acmeblahcorp']}}Part3:x和s选项使用x选项或s选项要求$regex与$option一起使用。例如,要指定i和s选项,必须使用$options来执行以下操作:{name:{$regex:/acme.*corp/,$options:"si"}}{name:{$regex:'极致。*corp',$options:"si"}}Part4:索引的使用对于区分大小写的正则表达式查询,如果字段有索引,MongoDB会把正则表达式与索引中的值进行匹配,比全表扫描速度更快。如果正则表达式是“前缀表达式”,可以优化查询速度,查询结果都会以同一个字符串开头。正则表达式也应该符合“最左前缀原则”,比如正则表达式/^abc.*/只会匹配以abc开头的索引值进行优化。Warning:警告1.虽然/^a/,/^a.*/和/^a.*$/匹配等价的字符串,但是它们的性能是不一样的。所有这些表达式都使用索引(如果存在的话);但是,/^a.*/和/^a.*$/速度较慢。这是因为/^a/可以在匹配前缀后停止扫描。2.不区分大小写的正则表达式查询通常不能使用索引,$regex不能使用不区分大小写的索引。Part5:在商品集合的例子中,存储了如下内容{"_id":100,"sku":"abc123","description":"Singlelinedescription."}{"_id":101,"sku":"abc789","description":"Firstline\nSecondline"}{"_id":102,"sku":"xyz456","description":"Manyspacesbeforeline"}{"_id":103,"sku":"xyz789","description":"Multiple\nlinedescription"}如果要对products集合进行查询,范围是sku列的内容以789结尾:db.products.find({sku:{$regex:/789$/}})结合MySQL的理解,上述查询在MySQL中是SQL:SELECT*FROMproductsWHEREskulike"%789";如果要查询以abc和ABC开头的sku,匹配时忽略大小写,可以使用i选项:db.products.find({sku:{$regex:/^ABC/i}}),查询结果是:{"_id":100,"sku":"abc123","description":"Singlelinedescription."}{"_id":101,"sku":"abc789","description":"第一行\n第二行"}Part6:m的使用如果要查询包含S开头的描述,并且想匹配/n之后的S开头,需要加上m选项db.products.find({description:{$regex:/^S/,$options:'m'}})返回:{"_id":100,"sku":"abc123","description":"Singlelinedescription."}{"_id":101,"sku":"abc789","description":"Firstline\nSecondline"}如果不加m选项,返回结果如下:{"_id":100,"sku":"abc123","description":"Singlelinedescription."}如果不使用^等锚点,将返回所有结果:db.products.find({description:{$regex:/S/}}){"_id":100,"sku":"abc123","description":"Singlelinedescription."}{"_id":101,"sku":"abc789","description":"Firstline\nSecondline"}Part7:使用s执行查询使用s选项将允许逗号。匹配所有字符,包括换行符。以下查询结果在description列以m开头,包含行字符串:db.products.find({description:{$regex:/m.*line/,$options:'si'}}){"_id":102,“sku”:“xyz456","description":"Manyspacesbeforeline"}{"_id":103,"sku":"xyz789","description":"Multiple\nlinedescription"}如果不包含s,则返回:{"_id":102,"sku":"xyz456","description":"Manyspacesbeforeline"}Part8:x的使用下面的例子使用x选项忽略空格和注释,用#表示注释,在\n中结束匹配模式:varpattern="abc#categorycode\n123#itemnumber"db.products.find({sku:{$regex:pattern,$options:"x"}})查询结果为:{"_id":100,"sku":"abc123","description":"Singlelinedescription."}可以看出abc和#category之间的空格以及#category和code之间的空格被忽略了。实际查询是sku是abc123,通过这些case总结出来的结果。我们可以了解MongoDB中regex的用法,以及它的可选参数$option的各个选项的含义和用法。由于作者水平有限,写作时间仓促,文章中难免存在一些错误或不准确的地方。不当之处敬请广大读者批评指正。如果喜欢作者的文章,请点击右上角一波关注,谢谢~