MongoDB 4.2 稳定版于近日正式发布了,此版本带来了许多最大的特性,比如分布式事务(Distributed Transactions)、客户端字段级别加密(Client-Side Field-Level Encryption)、按需物化视图(On-Demand Materialized Views)以及通配符索引(Wildcard Indexes)。下面我们来简单介绍一下各个新特性。

简单介绍 MongoDB是一个基于分布式文件存储的数据库 mongodb 分布式事务_Data

分布式事务和多文档事务

在 4.2 中,分布式事务(Distributed Transactions)和多文档事务(Multi-Document Transactions)都是称为分布式事务(distributed transactions)。使得分布到集群中不同 sharded 的多文档 ACID 事务变得更加简单。MongoDB 通过二阶段提交的方式,实现在多个 Shard 间发生的修改,要么同时发生,要么都不发生,保证事务的 ACID 特性。

除此之外,这个版本还删除事务的 16MB 总大小限制。在4.2 版本中,MongoDB 根据需要创建尽可能多的 oplog 实体(每个最大大小为 16MB),以封装事务中的所有写入操作。而在 MongoDB 4.0 中,MongoDB 为事务中的所有写操作创建单个条目,从而对事务强加 16MB 的总大小限制。

聚合能力提升

通过在聚合管道处理新数据时递增和丰富结果集,加速常见分析查询的性能。MongoDB 4.2 添加了 $merge 聚合阶段,通过这个新的阶段,我们可以:

  • 可以输出到相同或不同数据库中的集合。
  • 可以合并结果(比如合并文档,替换文档,保留现有文档,使操作失败,使用自定义更新管道处理文档)到现有集合中。
  • 可以输出到现有的分片集合。

新阶段允许用户创建按需物化视图,其中输出集合的内容可以在每次运行管道时逐步更新。除此之外,4.2 还增加了其他几个阶段,比如 $planCacheStats、$replaceWith、$set 以及 $unset ,由于篇幅原因,这些新阶段的内容可以参见 这里。

通配符索引(Wildcard Indexes)

此特性我们可以通过简单地定义过滤器以自动索引文档中所有匹配的字段,子文档和数组,为我们提供更加自然的数据建模和极大的索引支持。比如我们有以下场景的需求:管理员希望创建索引以支持 userMetadata 的任何子字段上的查询。userMetadata 的定义如下:

"userMetadata": { "likes": [ "dogs""cats"] } }"userMetadata": { "dislikes""pickles"} }"userMetadata": { "age": 45 } }"userMetadata""inactive"}

userMetadata 上的通配符索引可以支持 userMetadata,userMetadata.likes,userMetadata.dislikes 和 userMetadata.age 上的单字段查询,索引创建如下:

db.userData.createIndex( { "userMetadata.$**": 1 } )

这种索引可以支持以下的查询

db.userData.find({ "userMetadata.likes""dogs"})db.userData.find({ "userMetadata.dislikes""pickles"})db.userData.find({ "userMetadata.age": { $gt : 30 } })db.userData.find({ "userMetadata""inactive"})

而 userMetadata 上的非通配符索引只能支持对 userMetadata 值的查询。

Update 能力增强

在 4.2 版本之前,Update 操作基本上都是用确定的值更新某个字段。在新版本里,Update 能根据文档现有的字段内容来生成新的更新内容,如下的实例,根据文档 pay、tax 字段,加起来生成一个 total 字段;这个在 4.2 之前,用户需要先读取文档内容,获取 pay、tax 字段得到结果,然后调用 Update 设置新的字段。类似的特性还有很多,基本上 Aggregation 里能表达的更新操作,4.2 的 Update 命令都能支持。

更多关于 MongoDB 的新功能可以参见 Release Notes for MongoDB 4.2