对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。

MongoDB 9.0中的兼容性更改

本页介绍MongoDB 9.0 中引入的更改,这些更改可能会影响与旧版本MongoDB的兼容性。

已弃用
说明

prefixPreview, suffixPreview , substringPreview

从 MongoDB 9.0 开始,使用 text 算法的 prefixPreview、suffixPreview 和 substringPreview 查询类型已弃用并删除。取而代之,使用 prefix、suffix 或 substring 查询类型和 string 算法。

fleDisableSubstringPreviewParameterLimits

您无法覆盖 MongoDB 9.0 中针对加密字段的子字符串查询的内部限制。

从 MongoDB 9.0 开始,如果累加器表达式具有空字段名称,则 $group 阶段会返回错误。有关详细信息,请参阅 空字段名称 $group 限制。

从 MongoDB 9.0 开始,当显式设置 aggregate 选项时, 命令的 $queryStats 键将包含 allowPartialResults 选项。查询统计信息随后可以区分省略 allowPartialResults、显式设置为 true 或显式设置为 false 的请求。

此添加更改了设置 allowPartialResults 的 aggregate 查询的 key 和 keyHash 序列化。queryShapeHash 保持不变。匹配 keyHash 的下游消费者可能会观察到这些查询的不同值。

有关更多信息,请参阅 aggregate 命令查询结构。

从 MongoDB 9.0 开始,如果索引字段在引用该字段的查询运行时变为 多键 字段,则查询可能会失败并显示 QueryKilledError。当您插入或更新文档以使字段包含数组值时,索引字段将变为多键。

如果您的查询因该错误而失败,请在插入或更新操作完成后重新运行查询。

从 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。

从 MongoDB 9.0 开始,当您在副本集上的不同数据库之间重命名集合时,renameCollection 命令会对源集合和目标集合持有独占锁。该锁在整个操作期间持续,并会阻止 DDL 操作和对两个集合的写入。大多数读取操作使用无锁读取,不会被阻塞。

早期版本在 renameCollection 完成重命名之前释放了源集合的锁。在此窗口期间对源集合的并发写入可能会丢失。

此更改仅影响副本集。分片集群在重命名期间已锁定这两个集合。

从 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。

从 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。

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 驱动程序创建的数据。有关升级选项,请参阅以下部分。

如果可能,请创建新集合,而不是迁移使用公共预览版功能创建的集合:

  1. 将 MongoDB 服务器和驱动程序升级到 9.0。

  2. 配置新的加密集合,其名称与之前的集合不同。

  3. 插入新数据,或如有本地副本,则插入现有数据的未加密版本。

  4. 删除上一个集合。

如果不能使用新数据或没有现有数据的未加密版本:

  1. 将 MongoDB 服务器和驱动程序升级到 9.0

  2. 使用兼容 9.0 驱动程序,查询加密集合,对其进行解密。

  3. 将输出保存在本地。

  4. 配置新的加密集合并接收数据。

警告

  • mongoexport 和 mongodump 操作不会对集合进行解密。必须从驱动程序查询集合才能输出解密的数据。

  • MongoDB 9.0 兼容驱动程序无法查询为 MongoDB 8.2 加密的数据上的加密字段公开预览版查询类型。要解密数据,请查询未加密字段或查询整个集合。

以下部分提供了从部署中删除向后不兼容功能的信息。如果您要从MongoDB 9.0 降级到早期版本,查看以下部分,确保您的部署在降级后成功运行。

在 MongoDB 9.0 中,$convert 可以将对象转换为 binData。有关详细信息,请参阅将对象转换为 binData。

如果您创建了一个使用此转换的视图,则在降级到早期版本后,对该视图的查询将返回错误。

在从 9.0 降级之前,请更新或删除任何使用此转换的视图。