前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MongoDB 4.2亮点功能之——管道更新功能和查询功能

MongoDB 4.2亮点功能之——管道更新功能和查询功能

作者头像
MongoDB中文社区
修改2019-09-27 18:13:15
2.4K0
修改2019-09-27 18:13:15
举报
MongoDB中文社区(微信公众号:mongoing-mongoing)
MongoDB中文社区(微信公众号:mongoing-mongoing)

使用MongoDB时,如果需要比增、删、改、查操作更复杂的功能,过去我们会求助于聚合框架,装配出功能强大的操作管道,执行文档转换功能。在MongoDB 4.2中,管道功能被引入了update命令,使该命令的功能得到了极大提升。我们将向你介绍该命令的工作方式,再介绍新的聚合运算符以及4.2版本中的表达式,为你提供更多选项——三角函数、正则表达式和当前时间。

无处不在的管道

在何处使用聚合管道的问题现在已经发生了重大转变。以前,管道和aggregate 函数捆绑在一起。通过4.2版本,你还可以立即着手创建和使用管道,作为update和findAndModify命令的一部分。我们可以通过一个例子来说明这种改变。首先,让我们创建一个文档:

过去,如果我们想获取val1和val2的total(合计值),由于无法引用经过更新的字段,我们只能获取该文档,将两个变量相加,然后更新文档。

当然,这里包含了一次往返式的操作,如果不是为了举例的话,它可能是其他更新操作的一部分。聪明的MongoDB用户可能永远不会计算合计值并保存它,他们知道聚合管道有一个$sum运算符。它可以将值数组加进来,并使用$ notation引用相应字段,如下所示:

这个操作并未将数据持久化:

现在的情况是,这条聚合命令会处理整个集合的数据。我们需要增加一个$match执行阶段,将它的作用域设置到一个文档中…

只要我们能将聚合框架的功能带入update命令,就能解决这个问题。在MongoDB 4.2中,我们可以这样操作:

将聚合管道移入我们的更新命令,我们选定的文档就发生了相应变化。如果我们设定一个字段值,它就会被写入文档。这些全部发生在服务器上,没有数据往返的情况。它包含聚合框架的功能,可以在服务器上执行一个条件语句,如下所示:

对语句格式做一下修改,这样看起来更清楚一些:

这是MongoDB开发人员持续性任务的一部分,将查询语言和聚合操作统一起来,在每一处提供相同的功能。当谈到聚合框架中的改进之处时,还包括了使用聚合管道时用到的update和findAndModify命令。

如果你熟悉聚合框架,很有可能你想知道$set聚合执行阶段来自何处。在4.2版本中,它是一项新功能,但又不算太新;它是原有$addFields执行阶段的别名,设计它是为了实现语言的无缝统一。它是三个适用于更新操作的聚合执行阶段中的一个。每个阶段都有一个新的别名,连同原来聚合阶段的名称,如下所示:

- $set/$addFields

$unset/$project

$replaceWith/$replaceRoot

这些执行阶段允许你添加、移除字段或完全替换整个文档;在你更新文档时,可以完成你想要的所有操作。

平滑算子

在MongoDB 4.2推出之前,通用的三角函数计算功能是缺失的几项功能之一。在MongoDB 4.2中,一整套三角函数表达式被添加到聚合框架中,避免了功能缺失的风险。用$sin, $cos, $tan, $asin, $acos, $atan, $atan2, $asinh, $acosh和$atanh可以支持sin, cos, tan和它们的反函数以及反双曲线变量。所有这些表达式都接受弧度值,因此也支持$degreesToRadians和$radiansToDegrees这种换算表达式。

还有一种新设计的$round表达式,可以对数值做四舍五入处理,保留特定的整数和小数位。请注意,原来用于将数值截短为整数的$trunc表达式这一功能已经升级了,现在可以将数值截短,保留特定的整数和小数位,但该函数在使用旧的语法时还保留着过去的行为。

我们将所有这些函数一起放在一个查询实例中,仍然使用前面用过的文档:

我们得到val1的sine值,然后做四舍五入处理,并保留5位小数,将结果写回到文档,用作新的sin字段。

适用所有情况的正则表达式

MongoDB 4.2之前,你只能在聚合的$match执行阶段使用$regex运算符。这意味着,以前你只能将其用于匹配操作,而不能用于解析和抽取部分字符串。有了4.2版本,一切都改变了,有了三个新的运算符:$regexFind, $regexFindAll和$regexMatch。让我们演示一个简单的例子。首先,我们将一些字符串扔到文档中:

现在,我们希望捕获这段词组中出现的数字,但只捕获那些后面是numbers或digits的数字。我们使用([0-9]+) (numbers|digits)作为表达式。这个表达式获取的数字后跟的是正则表达式圆括弧中的单词。现在,我们在聚合中运行个表达式,查看得到的结果:

如果查看结果字段,我们会发现,取回的不仅仅是简单的是或否的匹配结果:

这里我们会看到返回的match字段,为我们提供了正确的字符串,这是由正则表达式工具匹配得出的。Idx字段表示该匹配结果距离源字符串开始的位置。最后,捕获数组返回的是匹配字符串的每个被捕获的部分——第一个元素是字符串中的数字,第二个元素是单词“numbers”或“digits”。对复杂的字符串解析工作来说,这个结果很理想。如果没有匹配上,$regexFind就会返回一个空值(null)。

使用$regexFind,你只能得到第一个匹配结果,并将它捕获回来。如果你找到了很多的匹配结果,接着使用$regexFindAll,就可以将所有匹配模式抽取到一个结果数组中,类似从$regexFind得到的结果。在这种情况下,如果没有匹配结果,就会返回一个空数组。

如果你想要的只是一个是或否的结果,即是否有结果与正则表达式相匹配,那么,使用$regexMatch就可以做到。

终于有了$$NOW

很多人想把时间戳嵌入到他们的文档中,而不需要反复回到客户端去获取文档时间。在4.2版本中,包含了$$NOW,这是一个在聚合管道中可以访问的变量,它返回的是用ISODate格式表示的当前时间。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Mongoing中文社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档