MongoDB正则表达式及应用

所属分类: 网络编程 / 正则表达式 阅读数: 1645
收藏 0 赞 0 分享

正则表达式常用来在所有语言中搜索字符串的任何模式或文字。MongoDB还提供了正则表达式功能的字符串模式使用正则表达式$regex操作符。MongoDB使用PCRE(Perl兼容正则表达式)为正则表达式语言。

不同于文本搜索,我们不需要做任何配置或命令就能直接使用正则表达式。

考虑下包含文字后其标签的帖子集合,文档结构如以下:

{
 "post_text": "enjoy the mongodb articles on yiibai",
 "tags": [
  "mongodb",
  "yiibai"
 ]
}

使用正则表达式表达

下面的正则表达式查询搜索所有包含字符串 yiibai.com 的帖子:

复制代码 代码如下:

>db.posts.find({post_text:{$regex:"yiibai.com"}})

同样的查询也可以写为:

>db.posts.find({post_text:/yiibai.com/})

使用正则表达式不区分大小写

为了使搜索不区分大小写,我们使用$options 带有值参数 $i。下面的命令会搜索字符串:yiibai.com,不论大小写:

复制代码 代码如下:

>db.posts.find({post_text:{$regex:"yiibai",$options:"$i"}})

该查询重新调整的结果是:其中在大小下包含词语 yiibai 文档,如以下:

{
 "_id" : ObjectId("53493d37d852429c10000004"),
 "post_text" : "hey! this is my post on Yiibai", 
 "tags" : [ "yiibai" ]
} 

使用正则表达式的数组元素:

我们还可以使用数组字段正则表达式概念。 这时候我们实现标签的功能显得尤为重要。 所以,如果想要搜索带有标签以词组tutorial开始所有的帖子(无论是tutorial或tutorials或tutorialjava或tutorialphp),都可以使用下面的代码:

复制代码 代码如下:

>db.posts.find({tags:{$regex:"tutorial"}})

优化正则表达式查询:

如果文档字段已被索引,查询将使用使用索引值的匹配正则表达式。 这使得搜索非常快,正则表达式相对于扫描整个集合。

如果正则表达式是一个前缀表达式,所有的匹配是以某一串字符开始。例如,如果正则表达式 ^tut, 查询有只搜索那些开始串 tut.

mongodb正则表达式应用

mongodb中完全支持正则表达式,一般查询中可以使用操作符$regex

db.lnmopy.find( { 'name': /*.lnmopy.com/i } )
db.lnmopy.find( { 'name': { $regex: '*.lnmopy.com', $options: 'i' } } )

以上两种完全等价,可以直接对域(field)即上例中的'name'键,使用正则表达式或者使用操作符,可选项目是i,即忽略大小写。
关于正则可选项,mongodb和其他语言标准正则稍有不同,有自己的标准。

$options的可选值

i 忽略大小写;

m 多行查找,如果内容里面不存在换行符号(例如 \n)或者构造上没有(start/end),该选项没有任何效果;
x 空白字符除了被转义的或在字符类中的以外完全被忽略,在未转义的字符类之外的 # 以及下一个换行符之间的所有字符,包括两头,也都被忽略;

s 圆点元字符(.)匹配所有的字符,包括换行符

假设我们有一个数据库名为mongoDemo

use mongoDemo

数据库中有个集合名为lnmopy

db.lnmopy.find()

有如下数据:

{ "_id" : ObjectId("502dd63d16a25b1ff6000000"), "name" : "www.lnmopy.com", "site" : "website", "tag" : "l,n,m,o,p,y"}
{ "_id" : ObjectId("502dd63d16a25b1ff6000000"), "name" : "demo.lnmopy.com", "site" : "unknown", "tag" : "d,e,m,o"}
{ "_id" : ObjectId("502dd63d16a25b1ff6000000"), "name" : "welcome.lnmopy.com", "site" : "website", "tag" : "w,e,l,c,o,m,e"}

mongodb的正则表达式仅支持i和m的javascript原生写法(如/*.lnmopy.com/i)。如果要是用x和s选项就必须使用“$regex”操作符并在“$options”中指定选项。

使用正则表达式的更新操作:

db.lnmopy.update( { 'name': /*.lnmopy.com/i }, { $set: { 'site':'www.lnmopy.com' } } );

意思是,查找当前数据库中名为“lnmopy”的集合中“name”字段符合“/*.lnmopy.com/i”正则的条目,并只将“site”字段更新为“www.lnmopy.com”,该条更新语句仅更新一条数据,如果不是用$set,那么这条记录就会只剩下你更新的部分和默认的ObjectId,可以说是替换了。如果想替换所有,可以加入参数:

db.lnmopy.update( { 'name': /*.lnmopy.com/i }, { $set: { 'site':'www.lnmopy.com' } } , false, true);

参数有顺序,false是upsert,如果没有就插入新的。true就是multi多条记录更新,所有匹配到的结果。或者直接指定{ multi: true }:
db.lnmopy.update( { 'name': /*.lnmopy.com/i }, { $set: { 'site':'www.lnmopy.com' } } , { multi: true });
这样就把所有的“site”字段全都更新为“www.lnmopy.com”了。

我设计的字段“tag”有个缺陷,就是本来是一个单词,现在每个字母都被“,“分隔开了。实际工作中也存在类似问题,由于批量转换数据,或者其他程序操作不当,或者业务需求更改等等原因需要对某些字段进行正则批量处理,mongodb的一般更新方法是不能实现的,这时就需要使用javascript语句。

正则表达式替换查询结果中','为”

db.lnmopy.find().forEach( function(u) { u.tag = u.tag.replace(/\,/, ""); db.lnmopy.save(u); } );

最后执行

db.lnmopy.find()

显示如下数据:

{ "_id" : ObjectId("502dd63d16a25b1ff6000000"), "name" : "www.lnmopy.com", "site" : "www.lnmopy.com", "tag" : "lnmopy"}
{ "_id" : ObjectId("502dd63d16a25b1ff6000000"), "name" : "demo.lnmopy.com", "site" : "www.lnmopy.com", "tag" : "demo"}
{ "_id" : ObjectId("502dd63d16a25b1ff6000000"), "name" : "welcome.lnmopy.com", "site" : "www.lnmopy.com", "tag" : "welcome"}

后记:javascript是mongodb的一大特色,也是优势,很多复杂的查询和处理都可以用javascript实现,要注意的是,javascript的工作效率较低,原则上应该尽量避免在主要业务逻辑中大量使用。类比的讲,javascript就相当于oracle的存储过程,介于10gen(mongodb的开发团队)是由oracle出来的这点,就一点也不奇怪了。关于如何使用更复杂的javascript,以后会写到。

更多精彩内容其他人还在看

正则表达式验证IPV4地址功能实例分析

这篇文章主要介绍了正则表达式验证IPV4地址功能,结合实例形式分析了IPV4地址验证的原理及具体实现技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

正则表达式教程之前后查找lookaround详解

这篇文章主要介绍了正则表达式教程之前后查找lookaround,结合具体问题分析了向前查找及向后查找功能的实现技巧与注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

正则匹配密码只能是数字和字母组合字符串功能【php与js实现】

这篇文章主要介绍了正则匹配密码只能是数字和字母组合字符串功能,涉及针对字符、数字等正则操作相关技巧,并给出了php与js实现示例,需要的朋友可以参考下
收藏 0 赞 0 分享

正则验证不能含有中文的实现方法【jQuery与java实现】

这篇文章主要介绍了正则验证不能含有中文的实现方法,结合jQuery与java两种实现方法分析了针对中文的正则验证操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

JS 密码强度校验的正则表达式(简单且好用)

最近在做一个通行证的项目,在项目中有这样的需求,注册模块中输入密码需要显示密码强度,今天小编给大家分享JS 密码强度校验的正则表达式,简单好用,需要的朋友参考下
收藏 0 赞 0 分享

iOS 正则表达式判断纯数字及匹配11位手机号码的方法

这篇文章主要介绍了iOS 正则表达式判断纯数字及匹配11位手机号码的方法,判断手机号码是否正确的方法很多,我是用正则表达式来完成匹配的,具体方法,大家参考下本文
收藏 0 赞 0 分享

正则表达式(简单易懂篇)

正则表达式是一种可以用于模式匹配和替换的强大工具。这篇文章主要介绍了正则表达式(简单易懂篇),需要的朋友参考下
收藏 0 赞 0 分享

正则表达式实现匹配连续数字的方法

我这两天刚刚学正则表达式。我觉的正则对连续的字符匹配很简单,但是对连续的一段数字匹配就不是很好。正好最近有朋友问了匹配连续数字的正则,就帮忙写了一下,算是当作温习一下吧。下面这篇文章就主要介绍了正则表达式实现匹配连续数字的方法。
收藏 0 赞 0 分享

正则表达式简介及在C++11中的简单使用教程

正则表达式(regular expression)是计算机科学中的一个概念,又称规则表达式,通常简写为regex、regexp、RE、regexps、regexes、regexen。接下来通过本文给大家介绍正则表达式简介及在C++11中的简单使用教程,一起通过本文学习吧
收藏 0 赞 0 分享

正则表达式实现最小匹配功能的方法

这篇文章主要介绍了正则表达式实现最小匹配功能的方法,结合具体实例形式分析了正则表达式最小匹配功能的原理与实现技巧,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多