MongoDB 3.6 中的兼容性更改

在本页面

以下 3.6 更改可能会影响与旧版本 MongoDB 的兼容性。

Localhost 绑定兼容性更改

从 MongoDB 3.6 开始,默认情况下,MongoDB 二进制文件mongodmongos绑定到 localhost(127.0.0.1)。如果为二进制文件设置了net.ipv6配置文件设置或--ipv6命令行选项,则该二进制文件还会绑定到 IPv6 地址::1

以前,从 MongoDB 2.6 开始,默认情况下,只有正式 MongoDB RPM(Red Hat,CentOS,Fedora Linux 和派生版本)和 DEB(Debian,Ubuntu 和派生版本)程序包中的二进制文件绑定到 localhost。

当仅绑定到 localhost 时,这些 MongoDB 3.6 二进制文件只能接受来自同一台计算机上运行的 Client 端(包括mongo shell,部署中其他成员(副本集和分片群集)的连接)。远程 Client 端无法连接到仅绑定到 localhost 的二进制文件。

要覆盖并绑定到其他 IP 地址,可以使用net.bindIp配置文件设置或--bind_ip命令行选项来指定 IP 地址列表。

Warning

绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication加强网络基础设施

例如,以下mongod实例同时绑定到 localhost 和示例 IP 地址198.51.100.1

mongod --bind_ip localhost,198.51.100.1

为了连接到该实例,远程 Client 端必须指定 IP 地址198.51.100.1或与该 IP 地址关联的主机名:

mongo --host 198.51.100.1

mongo --host My-Example-Associated-Hostname

要绑定到所有 IPv4 地址,您可以将绑定 IP 地址指定为0.0.0.0。要绑定到所有 IPv4 和 IPv6 地址,可以将绑定 ip 地址指定为0.0.0.0,::,或者使用新的net.bindIpAll设置或新的命令行选项--bind_ip_all

分片副本集

从 3.6 开始,分片必须是副本集。要将分片群集升级到版本 3.6,分片服务器必须作为副本集运行。

要将现有的分片独立实例转换为分片副本集,请参见将分片独立版转换为分片副本集

HTTP 接口和 REST API

MongoDB 3.6 删除了 MongoDB 弃用的 HTTP 接口和 REST API。

Configuration Settings mongod/mongos选项
net.http.enabled

net.http.JSONPEnabled
net.http.port
net.http.RESTInterfaceEnabled
httpinterface
nohttpinterface
jsonp
rest

Tools Changes

MongoDB 3.6 删除了弃用的mongooplog工具。

阵列操作兼容性更改

$ type:“数组”行为更改

从 3.6 开始,$type: "array"$type: 4表达式匹配包含任何元素类型的数组字段。

在早期版本中,$type : "array"仅匹配包含嵌套数组的数组字段。

例如,名为c的集合包含两个文档:

{ "_id": 1, "a": [ 1, 2, 3 ] },
{ "_id": 2, "a": [ 1, 2, [ 3, 4 ] ] }

以下操作按类型查询字段a

db.c.find( { "a": { $type : "array" } } )

从 3.6 开始,该查询返回集合中的两个文档,因为$type查询现在可以检测到字段a本身就是一个数组。

{ "_id": 1, "a": [ 1, 2, 3 ] },
{ "_id": 2, "a": [ 1, 2, [ 3, 4 ] ] }

在 3.4 和更低版本的 MongoDB 中,查询仅返回那些文档,其中数组字段a包含元素BSON的类型array

{ "_id": 2, "a": [ 1, 2, [ 3, 4 ] ] }

如果从具有部分索引的partialFilterExpression包含$type : "array"$type : 4表达式的 MongoDB 3.4.x 部署升级,则在升级后必须重新构建这些索引,以避免$type : 'array'语义冲突。

有关$type: "array"表达式的更多信息,请参见按数组类型查询

数组排序行为

从 3.6 开始,在对包含数组的字段进行排序时,MongoDB 会将字段的值最低的数组排在前,升序排序,数组的值最高的数组在降序。选择将用作 sort 键 的数组元素时,sort 不再考虑查询谓词。此行为更改适用于find命令和aggregation pipeline

由于此更改,当前按数组字段排序的应用程序可能会经历不同的排序 Sequences。

Important

由于 MongoDB 3.6 中对数组字段的排序行为发生了更改,因此在对以multikey index索引的数组上进行排序时,查询计划包括一个阻塞的 SORT 阶段。新的排序行为可能会对性能产生负面影响。

在阻塞式 SORT 中,必须在排序步骤中使用所有 Importing,然后才能产生输出。在非阻塞或“索引”排序中,排序步骤扫描索引以按请求的 Sequences 产生结果。

查找方法排序

排序键是 MongoDB 在排序过程中用来比较并最终对包含数组的文档进行排序的数组元素。在升序排序中,包含具有最低排序键值的数组的文档首先被排序。同样,在降序排序中,包含具有最高排序键值的数组的文档将首先排序。

在 MongoDB 3.4 和更早版本中,按数组字段进行排序时,在确定排序键时会考虑查询谓词。

例如,集合coll具有以下文档:

{ _id: 0, a: [-3, -2, 2, 3] }
{ _id: 1, a: [ 5, -4 ] }

考虑对集合的数组字段a进行以下排序操作:

db.coll.find({a: {$gte: 0}}).sort({a: 1});

在 MongoDB 3.6 中,排序操作在确定其排序键时不再考虑查询谓词。因此,排序键是每个文档中价值最低的元素:

该操作按以下 Sequences 返回文档:

{ "_id" : 1, "a" : [ 5, -4 ] }
{ "_id" : 0, "a" : [ -3, -2, 2, 3 ] }

以前的 MongoDB 版本使用与查询谓词{$gte: 0}匹配的最低值数组元素作为排序键:

并将按以下 Sequences 返回文档:

{ _id: 0, a: [-3, -2, 2, 3] }
{ _id: 1, a: [ 5, -4 ] }

汇总方法排序

在 MongoDB 3.6 中,使用db.collection.aggregate()方法对数组字段进行排序时,仅单个数组元素用作排序键。

考虑以下示例:

// Documents.
{ "_id" : 1, "timestamps" : [ ISODate("2017-07-15T15:31:01Z"), ISODate("2017-07-21T18:31:01Z") ] }
{ "_id" : 0, "timestamps" : [ ISODate("2017-07-21T15:31:01Z"), ISODate("2017-07-21T13:31:01Z") ] }

// Query.
db.c.aggregate([{$sort: {timestamps: -1}}])

对于降序排序,将数组中的最新时间用作排序键:3:31 PM on July 21用于具有_id: 0的文档,5:31 PM on July 21用于具有_id: 1的文档。由于排序是递减的,因此这些键从最新到最近的 Sequences 进行排序,从而导致_id: 1的文档在_id: 0的文档之前进行排序。

在 3.6 之前的版本中,“整个数组”用作聚合排序的排序键。数组排序键在元素方面进行比较以确定结果集的排序 Sequences。

Example

// Documents.
{_id: 0, a: [3, 1, 5]}
{_id: 1, a: [3, 4, 0]}

// Query.
db.coll.aggregate([{$sort: {a: 1}}])

在 3.6 之前的版本中,排序键分别为[3,1,5]和[3,4,0]。由于第一个数组元素相等,因此第二个数组元素 break 平局,并且文档以_id: 0排序。

有关使用Aggregation Pipeline进行排序的更多信息,请参见$sort

使用复合排序模式对多个具有聚合的数组字段进行排序

在 MongoDB 3.6 中,当以aggregation pipeline进行排序时,MongoDB 不能再对排序字段中包含* parallel array *的文档进行排序。如果数组是 BSON 对象的兄弟元素,则认为它们是并行的。涉及嵌套数组的排序键不被认为是并行的,也不能将与前缀共享同一数组的排序键视为并行。

Note

使用find进行排序始终存在此行为,但现在在 3.6 中,findaggregate共享相同的语义。

Example

集合包含以下文档:

{a: [ {b: [1, 2]}, {b: [3, 4]} ]}

以下聚合成功,因为排序是在嵌套数组上执行的:

db.coll.aggregate([{$sort: {"a.b": 1}}])

Example

同样,如果集合包含以下文档:

{a: [{b: 1, c: 1}, {b: 2, c: 2}]}

由于排序键与前缀共享相同的数组,因此以下聚合成功:

db.coll.aggregate([{$sort: {"a.b": 1, "a.c": 1}}])

Example

但是,在包含以下文档的集合中:

{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ]}
{ _id: 2, a: [ -3, 5 ], b: 0 }
{ _id: 3, a: [ -6, 12 ], b: 100 }

以下排序操作失败:

db.coll.aggregate([ { $sort: {a: 1, b: 1} } ])

MongoDB 无法同时对ab字段进行排序,因为在带有_id : 1的文档中,同级字段ab都是数组。结果,MongoDB 在排序键生成期间遇到了并行数组,并返回错误。

更新操作更改

更新中的新字段

从 MongoDB 3.6 开始,通过update操作添加的新字段将按字典 Sequences 附加。

例如,集合coll具有以下文档:

{ _id: 0, x: 0 }

以下更新操作将两个新字段添加到文档中:

db.coll.update({_id: 0}, {$set: {b: 0, a: 0}})

从 3.6 开始,MongoDB 以字典 Sequences 附加新字段。更新的文档将为{_id : 0, x: 0, a: 0, b: 0}

MongoDB 的早期版本按更新文档中出现的 Sequences 附加新字段。更新的文档将为{_id : 0, x: 0, b: 0, a: 0}

与 arrayFilters 标识符冲突的字段

从 MongoDB 3.6 开始,与arrayFilters标识符冲突的字段将无法再更新。

例如,集合coll具有以下文档:

{ _id: 0, x: { "$[]": 0 } }

以下更新在 MongoDB 的早期版本中成功进行:

db.coll.update({_id: 0}, {$set: {"x.$[]": 1}})

在 MongoDB 3.6 中,更新失败,因为字段名称“ $ []”与arrayFilters标识符语法冲突。有关arrayFilters的更多信息,请参见指定用于阵列更新操作的 arrayFilters

Note

仅当featureCompatibilityVersion设置为 3.6 时,新的更新行为才适用。

$ pop 参数的更严格验证

从 3.6 [1]开始,$pop运算符对其参数进行更严格的验证,以要求:

在早期版本中,$pop允许:

[1] 影响featureCompatibilityVersion设置为3.6的 MongoDB 部署;例如新的 3.6 部署,已将featureCompatibilityVersion设置为3.6的升级部署。

删除$ pushAll 更新操作符

MongoDB 3.6 删除了弃用的$pushAll运算符。从 2.4 开始不推荐使用该运算符。

代替$pushAll,将$push运算符与$each修饰符一起使用。例如:

db.students.update(
   { name: "joe" },
   { $push: { scores: { $each: [ 90, 92, 85 ] } } }
)

Platform Support

通用兼容性更改

MONGODB-CR Deprecation

从 MongoDB 3.6 开始,不推荐使用MONGODB-CR身份验证机制。如果尚未将MONGODB-CR身份验证架构升级到 SCRAM,请参见升级到 SCRAM

仲裁人和优先级

从 MongoDB 3.6 开始,仲裁者的优先级为0。将副本集升级到 MongoDB 3.6 时,如果现有配置的仲裁者的优先级为1,则 MongoDB 3.6 会将仲裁器的优先级重新配置为0

弃用主从复制

MongoDB 3.6 不赞成使用主从复制。

-WiredTiger 的 nojournal 选项

在版本 3.6 中,使用WiredTiger 存储引擎弃用了副本集成员--nojournal选项。

使用 WiredTiger storage engine副本集成员不应使用--nojournal选项。有关日记的更多信息,请参见Manage Journaling

汇总命令和结果

MongoDB 3.6 删除了aggregate命令的选项以将其结果作为单个文档返回。

如果运行aggregate命令,则必须包括cursor选项或explain选项。

大多数用户不应直接运行aggregate命令,而应使用 mongo shell 中提供的db.collection.aggregate()帮助程序或驱动程序中的等效帮助程序。这些助手将返回一个光标,除非使用explain选项。

字符串强制转换的汇总日期

从 3.6 开始,在聚合表达式中强制转换为字符串的日期将包含毫秒,并附加字母'Z'。

Example

// Documents.
{_id: 0, d: ISODate("2017-10-18T20:04:27.978Z")}
{_id: 1, d: ISODate("2017-10-18T20:04:28.192Z")}

// Query.
db.coll.aggregate({$project: {d: {$toLower: "$d"}}})

在 3.6 之前,这将分别返回日期为d: "2017-10-18t20:04:27"d: "2017-10-18t20:04:28"。在 3.6 中,结果包括毫秒和字母“ Z”:d: "2017-10-18t20:04:27.978z"d: "2017-10-18t20:04:28.192z"

该更改适用于以下聚合运算符:

删除诊断日志记录命令和选项

MongoDB 3.6 删除了已弃用的diagLogging命令和mongod --diaglog选项。而是使用mongoreplay捕获,重播和分析发送到您的 MongoDB 部署的命令。

validate Operation

从 MongoDB 3.6 开始,对于 WiredTiger 存储引擎,只有full验证过程将强制检查点并将所有内存中数据刷新到磁盘,然后再验证磁盘上的数据。

在以前的版本中,WT 存储引擎的数据验证过程始终强制执行检查点。

有关验证操作的更多信息,请参见validate命令和db.collection.validate()方法。

名为*的索引

从 3.6 开始,不能在创建索引的过程中将*指定为索引名,也不能通过指定索引键来删除名为*的索引。

要删除名为*的现有索引,请在升级之前删除该索引。要重命名它们,请删除并重新创建索引。

Deprecated Options

在版本 3.6.1 中更改。

对于 MMAPv1,请使用{ _id: 1}索引上的hint()来防止光标在返回的文档中多次返回(如果中间的写操作导致文档移动)。

对于其他存储引擎,请改用hint(){ $natural : 1 }

[2] 从版本 4.0 开始,MongoDB 为副本集提供多文档事务。

向后不兼容的功能

以下 3.6 个功能要求将featureCompatibilityVersion设置为"3.6"

3 .6 部署具有以下默认featureCompatibilityVersion值:

Deployments featureCompatibilityVersion
对于新的 3.6 部署 "3.6"
对于部署从 3.4 升级 "3.4",直到您setFeatureCompatibilityVersion"3.6"为止。

要查看featureCompatibilityVersion,请参见View FeatureCompatibilityVersion

如果需要从 3.6 降级,则必须在降级二进制文件之前从数据库中删除与所有持久性不兼容功能有关的数据。请参阅 3.6 降级过程。

首页