本页介绍MongoDB 9.0 中引入的更改,这些更改可能会影响与旧版本MongoDB的兼容性。
弃用
已弃用 | 说明 |
|---|---|
| 从 MongoDB 9.0 开始,使用 |
| 您无法覆盖 MongoDB 9.0 中针对加密字段的子字符串查询的内部限制。 |
聚合(Aggregation)
中的空字段名称 $group
从 MongoDB 9.0 开始,如果累加器表达式具有空字段名称,则 $group 阶段会返回错误。有关详细信息,请参阅 空字段名称 $group 限制。
allowPartialResults 在聚合 $queryStats 键中
从 MongoDB 9.0 开始,当显式设置 aggregate 选项时, 命令的 $queryStats 键将包含 allowPartialResults 选项。查询统计信息随后可以区分省略 allowPartialResults、显式设置为 true 或显式设置为 false 的请求。
此添加更改了设置 allowPartialResults 的 aggregate 查询的 key 和 keyHash 序列化。queryShapeHash 保持不变。匹配 keyHash 的下游消费者可能会观察到这些查询的不同值。
有关更多信息,请参阅 aggregate 命令查询结构。
一般性变更
当索引字段变为多键时查询失败
从 MongoDB 9.0 开始,如果索引字段在引用该字段的查询运行时变为 多键 字段,则查询可能会失败并显示 QueryKilledError。当您插入或更新文档以使字段包含数组值时,索引字段将变为多键。
如果您的查询因该错误而失败,请在插入或更新操作完成后重新运行查询。
Change Streams 在选举后实施读取偏好(read preference)
从 MongoDB 9.0 开始,如果副本集选举改变了节点的角色,使其不再满足读取偏好(read preference),则使用 primary 或 secondary 的 readPreference 打开的变更流将从 getMore 返回可恢复错误 InterruptedDueToReplStateChange(错误代码 11602)。在早期版本中,游标会持续从同一个节点返回结果。
兼容的驱动程序和 mongos 会从上一个恢复令牌自动恢复。手动 getMore 循环和 mongosh 必须使用 resumeAfter 恢复。有关详细信息,请参阅 恢复变更流。
地理空间索引键提取错误代码
从 MongoDB 9.0 开始,2dsphere 索引键提取失败会返回命名错误代码 510 (GeoKeyExtractionFailed) 和 511 (GeoKeyExtractionFailedTimeseries)。这些代码取代了之前常规 2dsphere 索引的断言代码 16755 和 16756,以及时间序列集合的 183934 和 183493。如果您的应用程序匹配之前的代码,请更新它以匹配 510 和 511。
针对跨数据库的更强大的集合锁 renameCollection
从 MongoDB 9.0 开始,当您在副本集上的不同数据库之间重命名集合时,renameCollection 命令会对源集合和目标集合持有独占锁。该锁在整个操作期间持续,并会阻止 DDL 操作和对两个集合的写入。大多数读取操作使用无锁读取,不会被阻塞。
早期版本在 renameCollection 完成重命名之前释放了源集合的锁。在此窗口期间对源集合的并发写入可能会丢失。
此更改仅影响副本集。分片集群在重命名期间已锁定这两个集合。
服务器端 JavaScript 日期操作使用 UTC
从 MongoDB 9.0 开始,服务器端 JavaScript 在基于 WebAssembly (WASM) 的引擎上运行,该引擎以 UTC 格式评估本地 Date 操作,而不考虑 mongod 托管时区。在早期版本中,这些操作遵循托管时区。此更改会影响在 $function、$accumulator、$where 和 mapReduce 中运行的 JavaScript。
存储的 BSON 日期值保持不变,Date.prototype.getTime()、Date.prototype.toISOString() 和 getUTC*() 等 UTC 操作也是如此。这种差异会影响本地时间操作:
Date.prototype.toString()Date.prototype.toTimeString()Date.prototype.getHours()以及其他本地 getter本地
Date构造函数和设置器将日期隐式转换为字符串的操作,包括在没有比较器的情况下调用的
Array.prototype.sort()
考虑在运行 TZ=America/New_York 的 mongod 上执行以下操作:
db.events.insertOne( { name: "before-opening", occurredAt: ISODate("2024-01-15T13:30:00Z")} )
db.events.find( { $expr: { $function: { body: function(date) { return date.getHours() < 9; }, args: [ "$occurredAt" ], lang: "js" } }} )在早期版本中,13:30 UTC 是纽约的 08:30,因此 getHours() 返回 8,并且查询匹配文档。从 MongoDB 9.0 开始,getHours() 返回 13,并且查询不匹配。操作在两个版本中都成功,因为存储的日期仍然有效,因此,差异不会报告为错误。运行混合二进制版本的部署可以对相同的 JavaScript 返回不同的结果。
升级影响
在升级到 MongoDB 9.0 之前,请查看 $function、$accumulator、$where 和 mapReduce 代码中的 JavaScript 以了解本地 Date 使用情况,并且不要依赖 mongod 托管区域。
要评估指定时区中的日期,请使用带有显式 timezone 参数的聚合日期操作符,而不是 JavaScript。以下查询在所有版本中返回相同的结果:
db.events.find( { $expr: { $lt: [ { $hour: { date: "$occurredAt", timezone: "America/New_York" } }, 9 ] }} )对于需要确定性比较或序列化的 JavaScript,请使用 getTime()、toISOString() 或 getUTC*() 方法,而不是本地 Date 方法或隐式 string 转换。当排序后的值可能包含日期时,请将显式比较器传递给 Array.prototype.sort()。
要了解更多信息,请参阅 服务器端 JavaScript。
服务器端 JavaScript 不可用 ppc64le
从 MongoDB 9.0 开始,服务器端 JavaScript 在 ppc64le 架构上不可用。ppc64le 的 mongod 和 mongos 二进制文件不包含 JavaScript 引擎。因此,$function、$accumulator、$where 和 mapReduce 操作在该架构上会失败。早期版本在 ppc64le 上运行这些操作。
您无法通过配置文件设置或命令行选项在 ppc64le 上启用服务器端 JavaScript。
升级影响
在将 ppc64le 部署升级到 MongoDB 9.0 之前,请确定使用 $function、$accumulator、$where 或 mapReduce 的应用程序。重写这些操作以使用不需要服务器端 JavaScript 的 聚合管道阶段和操作符。您也可以在采用不同架构的部署上运行这些操作。
要了解更多信息,请参阅 服务器端 JavaScript。
安全性
Queryable Encryption 前缀、后缀和子字符串从公共预览版迁移到 GA
MongoDB 9.0 标志着在启用了 Queryable Encryption 的集合中,对加密 string 字段进行前缀、后缀和子字符串查询的功能正式发布 (GA)。该 GA 功能与 MongoDB 8.2 中发布的公共预览版不兼容,鉴于该功能现已正式发布,不应再使用该预览版。
要将前缀、后缀或子字符串查询与 Queryable Encryption 结合使用,MongoDB 的版本必须为 9.0 或更高版本,并使用 9.0 兼容的驱动程序。如果您仍在使用公共预览版,MongoDB 必须保持在 8.2 或 8.3 版本,并使用 8.2 或 8.3兼容的驱动程序。
MongoDB 9.0 驱动程序可以解密用 MongoDB 8.2 或 8.3 驱动程序创建的数据。有关升级选项,请参阅以下部分。
重新开始(首选)
如果可能,请创建新集合,而不是迁移使用公共预览版功能创建的集合:
将 MongoDB 服务器和驱动程序升级到 9.0。
配置新的加密集合,其名称与之前的集合不同。
插入新数据,或如有本地副本,则插入现有数据的未加密版本。
删除上一个集合。
迁移现有数据
如果不能使用新数据或没有现有数据的未加密版本:
将 MongoDB 服务器和驱动程序升级到 9.0
使用兼容 9.0 驱动程序,查询加密集合,对其进行解密。
将输出保存在本地。
配置新的加密集合并接收数据。
警告
mongoexport和mongodump操作不会对集合进行解密。必须从驱动程序查询集合才能输出解密的数据。MongoDB 9.0 兼容驱动程序无法查询为 MongoDB 8.2 加密的数据上的加密字段公开预览版查询类型。要解密数据,请查询未加密字段或查询整个集合。
向后不兼容的功能
以下部分提供了从部署中删除向后不兼容功能的信息。如果您要从MongoDB 9.0 降级到早期版本,查看以下部分,确保您的部署在降级后成功运行。
视图中的表达式
在 MongoDB 9.0 中,$convert 可以将对象转换为 binData。有关详细信息,请参阅将对象转换为 binData。
如果您创建了一个使用此转换的视图,则在降级到早期版本后,对该视图的查询将返回错误。
在从 9.0 降级之前,请更新或删除任何使用此转换的视图。