Mongoose CHANGELOG 深度解读:从 9.9.5 回溯 9.x 系列的核心变更、破坏性改动与性能演进
【免费下载链接】mongooseMongoDB object modeling designed to work in an asynchronous environment.项目地址: https://gitcode.com/GitHub_Trending/mo/mongoose
本指南以当前仓库根目录下的 CHANGELOG.md(覆盖 962 个版本条目、从 9.9.5 一直回溯到 8.x/7.x/6.x 各维护分支)为骨架,系统梳理 Mongoose 9.x 系列引入的新特性、破坏性变更、性能优化与 TypeScript 类型演进,并对照 lib 源码与 docs 文档给出落地依据。读完本文,你将掌握 Mongoose 9 相比 8.x 的关键差异、9.x 迭代中的新 API 与配置项,以及如何结合 CHANGELOG 制定自己的升级与排查策略。
一、Mongoose 版本发布节奏与多分支维护策略
CHANGELOG 的头部清晰地展示了 Mongoose 的版本管理方式:主版本 9.x 与旧主版本 8.x、7.x、6.x 并行发布,例如同一时间段内同时出现:
9.9.5 / 2026-09-048.24.4 / 2026-08-217.8.9 / 2026-02-046.13.8 / 2025-01-20
从 docs/version-support.md 可以确认对应的维护策略:
| 版本线 | 状态 | 说明 |
|---|---|---|
| Mongoose 9 | 当前版本 | 2025-11-21 发布,新功能集中于此 |
| Mongoose 8 | 先前版本 | 2023-10-31 发布,8.x 持续接收修复至少到 2026-02-01 |
| Mongoose 7 | 旧版 | 2023-02-27 发布,处于遗留支持状态 |
| Mongoose 6 | 有限维护 | 仅安全补丁与请求的 bug 修复,2027-02-01 停止一切更新 |
| Mongoose 5 | 生命周期结束 | 2024-03-01 EOL |
这种「一条主线 + 多条维护分支」的节奏意味着:当你升级 Mongoose 时,不仅要看 9.x 的新功能,还要注意 8.x/7.x 分支上的修复回移(backport)。例如8.24.4明确标注了(8.x backport),8.23.0则把flattenUUIDs特性回移到了 8.x 线。当前仓库 package.json 中version为9.9.5,与 CHANGELOG 头部条目一致。
二、Mongoose 9.0.0:一次彻底的大版本重构
CHANGELOG 中9.0.0 / 2025-11-21条目集中列出了全部BREAKING CHANGE,这是从 8.x 升级时必须逐条核对的内容,主要可分为四类。
1. 中间件与回调模型的变化
- 彻底移除基于回调的 pre 中间件:
pre()钩子不再接收next()参数。9.0.0 的迁移指南 docs/migrating_to_9.md 给出了对照写法:
// Mongoose 8.x:不再支持 schema.pre('save', function(next) { // 异步操作 next(); }); // Mongoose 9.x:async/await 或 Promise schema.pre('save', async function() { // 异步操作 }); schema.pre('save', function() { return new Promise((resolve) => { // 异步操作 resolve(); }); });- 验证路径异步化:
SchemaType.prototype.doValidate()改为返回 Promise(async function doValidate(value, scope, options)),不再接受回调;validate()也改为 async 函数并直接调用 Kareem 钩子(相关代码见 lib/schemaType.js)。 - 移除
_executionStack,以获得更清晰的错误堆栈;移除schemaType.caster/casterConstructor属性,改用embeddedSchemaType与Constructor。
2. 驱动与依赖升级
- 升级到 MongoDB Node.js Driver v7(9.0.0),随后 9.6.0 升级到 driver 7.2、9.8.0 升级到 driver 7.5;package.json 中
mongodb: "~7.5"与之一致。 - 移除
bson直接依赖,统一通过mongodb/lib/bson使用 BSON(9.9.2 的类型层面也从bson改为从mongodb导入)。 - 移除浏览器构建,改为独立的
@mongoosejs/browser包。
3. 查询语义收紧
findOne(null)、find(null)等直接抛错,不再静默返回首条文档。- 更新管道(update pipeline)默认禁用:向
updateOne()/updateMany()/findOneAndUpdate()传入管道数组会抛错,必须显式开启updatePipeline: true。 FilterQuery属性在 TypeScript 中不再退化为any;create()与insertOne()参数类型更严格。
4. 类型系统与命名修正
id从 Document 基类属性改为虚拟属性(_id相关类型随之调整)。RootQuerySelector、Condition等类型与 MongoDB driver 类型合并统一。- 复数化修正:
virus -> viruses(这也提醒你,集合名自动复数化可能出现与旧库不一致的情况)。
三、9.x 系列值得关注的新特性
CHANGELOG 中大量feat前缀条目记录了 9.x 的功能演进,以下按模块分类。
Schema 与验证
strictRead选项(9.8.0):在文档水合(hydration)阶段过滤或抛错处理不在 schema 中的字段。源码 lib/document.js 中init()会读取docSchema.options.strictRead,当路径类型为adhocOrUndefined且strictRead为'throw'时抛出StrictModeError,为true时直接跳过该字段。对应文档说明见 docs/guide.md 中的strictRead小节。allowNull选项(9.6.0):即使字段非required,也可以禁止null值。实现位于 lib/schemaType.js,required: true与allowNull: false同时指定会抛出错误;错误消息见 lib/error/messages.js。- Union Schema 支持(8.18.0 起,9.x 持续完善):
toJSONSchema支持 union、union 的验证与子文档实现,以及对 union 应用 create 强转时的基本类型转换。 flattenUUIDs选项(9.2.0):toObject()与toJSON()可展开 UUID,8.23.0 已回移。toJSONSchema()完善:9.7.1 为 ObjectId 输出 regex 模式、9.4.0 支持 unions、9.9.2 修复 enum 重复null与 object 形式 enum。
Model 与查询
pathsToSave(9.1.0):save()仅保存指定路径,9.8.0 补充了SaveOptions.pathsToSave类型,9.2.2 修正其对所有更新操作符的过滤行为。- 乐观并发增强:9.1.0 增加
optimisticConcurrency的 exclude 选项;9.4.0/9.8.0/9.9.2 修复了嵌套路径、排除父路径、map 通配符等场景下的版本键处理。 returnDocument全局选项(9.2.0):新增全局returnDocument,同时弃用returnOriginal与new(9.9.3 文档进一步补充)。- 跳过中间件选项(9.2.0):可在调用时跳过 middleware 执行(对应 issue #15883)。
bulkSave()完善:9.8.0 修复插入新文档时的版本键处理,9.9.2 确保事务重试时文档会话被设置,9.9.4 按文档 id 索引 bulkSave 写错误以提升性能。hydrate()增强:9.2.0 支持strict选项,8.19.0 支持virtuals选项。
聚合与驱动能力
pipelineForUnionWith()(9.3.0,8.24.0 回移):复用管道与$unionWith组合,TypeScript 友好。- Node.js TracingChannel 支持(9.7.0):为 APM 埋点提供能力,实现见 lib/tracing.js,使用
node:diagnostics_channel。 - Standard Schema 适配(9.7.0):为 Model 增加标准 schema 适配器,类型层改为使用
@standard-schema/spec(9.7.3),与 package.json 依赖一致。
四、性能优化路线:9.x 的持续调优
CHANGELOG 中perf前缀条目在 9.x 后期显著增多,形成了一条清晰的性能优化主线:
toObject()/toJSON():9.9.0 用更快的字符串检查、避免在无 getter 路径上调用isSelected,9.9.3 缓存投影元数据、对扁平投影避免扫描全部投影路径。save()链路:9.1.2 仅选择_id检查文档存在性;9.7.1 减少不必要的 Promise 分配与路径/默认值/脏状态开销;9.8.1 避免重复构建 modified paths、避免每次实例化文档都清空 required paths 缓存。insertMany()与变更追踪:9.9.0 提升insertMany()与通用变更追踪性能。- 时间戳:9.9.0 除非 upsert 被设置,否则不为
createdAt添加$setOnInsert。 - 杂项:9.8.1 缓存
array.unique的toString()结果;9.9.2 内联$__hasOnlyPrimitiveValues()中的类型检查;8.20.3 使用Object.hasOwn替代hasOwnProperty。
这些优化大多伴随对应 issue 编号(如 #14394、#16373、#16385),在排障时可反向追踪具体提交。
五、TypeScript 类型系统的持续演进
9.x 的类型工作贯穿始终,CHANGELOG 中types(...)前缀条目密集:
- 推断能力:
InferRawDocType/InferHydratedDocType的持续修正(子文档、文档数组、嵌套 map、union 分发),9.3.3 使MergeType对 union 具有分配性。 - 严格化:
FilterQuery不再回退到any;exactOptionalPropertyTypes编译支持(9.6.2);查询过滤类型尊重字符串联合与 enum(9.6.0);对$and中无法识别的操作符报类型错误(9.4.0)。 - 文档类型细节:
id虚拟属性默认加入HydratedDocument<>;toObject()保留已 populate 路径(除非depopulate: true);Model.schema在省略TSchema时仍保持类型。 - 工具链:9.2.2 引入 TSTyche 做类型测试(对应脚本
test:types见 package.json),并逐步替换 tsd。
六、典型 Bug 修复模式:值得记住的「坑」
CHANGELOG 的fix条目是对实际使用最有参考价值的部分,几个高频主题值得注意:
- sanitizeFilter 防护:8.24.3/9.9.2 将
sanitizeFilter应用到countDocuments()与cursor();9.1.6 处理其他顶层查询操作符;9.5.0 修复__proto__相关更新与$set方法的误判。 - 原型污染防护:9.2.2 修复
setDefaultsOnInsert的点号路径处理并防止原型污染;9.1.4 防止访问原型上的嵌套路径导致崩溃。 - 数组子文档路径重建:8.24.1/9.7.2 在数组重排与删除后重新索引 subdoc,保证后续嵌套修改保存到正确路径(对应 lib/types/documentArray 相关逻辑)。
- 地图(Map)路径:9.9.4 修复移除 map 路径时子路径清理、嵌套路径下 map 的移除,以及克隆时 map 值 schematype 的单例保持。
optimisticConcurrency与排除路径:9.8.0 修复乐观并发下被排除父路径的处理,9.9.2 支持 map 通配符。
七、文档与生态建设
9.x 在文档层面也有不少投入,CHANGELOG 记录了:
- 新增 Atlas Vector Search 与 Atlas Search 文档(9.9.4)。
- 生成
llms.txt(9.7.0),并有配套脚本 scripts/generateLLMsTXT.js。 - 加入 MongoDB Knowledge 助手侧边栏(9.7.1)、深色模式(9.0.1)、代码块复制按钮(8.20.1)。
- 大量链接修复与文档重写(documents docs 重写、populate 选项补充、
sample()示例扩展等)。
八、升级建议与阅读方法
结合 CHANGELOG 与迁移文档,推荐的升级路径是:
- 先读迁移指南:若从 8.x 升级到 9.x,通读 docs/migrating_to_9.md;更早版本需逐级升级(7.x → 8.x → 9.x),对应 docs/migrating_to_8.md 等文档。
- 逐条核对 BREAKING CHANGE:以 9.0.0 条目的破坏性改动为清单,重点检查 pre 中间件
next()、更新管道、findOne(null)、id虚拟属性等。 - 关注本版本线的新特性:9.8.0 的
strictRead、9.6.0 的allowNull、9.2.0 的returnDocument都是可能直接改变业务行为的配置项,可结合 docs/guide.md 与 lib/schema.js 的默认值确认行为。 - 把 perf/fix 条目当作升级红利:9.x 后期的性能优化(toObject、save、insertMany)在升级后通常无需改代码即可受益。
- 注意跨分支行为差异:8.x 与 9.x 并行的修复(如 sanitizeFilter、clone 隔离)语义可能不完全一致,测试要覆盖两个目标版本。
最后,升级后建议运行仓库自带的测试体系做验证:npm test(Mocha 全量测试)、npm run test:types(TSTyche 类型测试,配置见 tstyche.json),并在升级前用npm ls mongoose mongodb确认依赖树中没有锁死旧驱动的包。
【免费下载链接】mongooseMongoDB object modeling designed to work in an asynchronous environment.项目地址: https://gitcode.com/GitHub_Trending/mo/mongoose
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考