You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB GridFS报grid.mongo.ObjectID is not a constructor错误咨询

错误原因
  • 你使用的gridfs-stream包与Mongoose 6.x及以上版本不兼容:Mongoose 6开始将原mongoose.mongo.ObjectID(末尾大写D)重命名为mongoose.mongo.ObjectId(末尾小写d),但gridfs-stream内部仍然在调用大写D的ObjectID构造函数,因此触发类型错误。
  • 额外说明:gridfs-stream包已经多年未更新,本身不兼容新版MongoDB/Mongoose生态。
修复方案

方案1:快速兼容修复(无需更换依赖)

在初始化GridFS实例后,手动给grid.mongo.ObjectID赋值指向正确的构造函数即可,修改你的creatConnectionGridFs方法:

private creatConnectionGridFs(): void {
  const connection = mongoose.createConnection(`${process.env.MONGODB}`);
  connection.once('open', () => {
    this.gridFs = Grid(connection.db, mongoose.mongo);
    // 新增下面这行手动映射兼容
    this.gridFs.mongo.ObjectID = mongoose.mongo.ObjectId;
    this.gridFs.collection('uploads');
  });
}

修改后原有调用createReadStream的代码不需要变动,即可正常运行。

方案2:使用原生GridFSBucket(更稳定,推荐)

新版MongoDB Node驱动已经内置了GridFS操作能力,不需要额外依赖第三方gridfs-stream包,可直接替换实现:
首先删除gridfs-stream相关依赖和类型定义,修改代码如下:

import { GridFSBucket } from 'mongodb';

export default class UploadController {
  private gridFsBucket: GridFSBucket;
  constructor() {
    autoBine(this);
    this.creatConnectionGridFs();
  }

  getImageByName(req: Request, res: Response, next: NextFunction) {
    from(this.gridFsBucket.find({ filename: req.params.filename }).toArray())
      .pipe(
        switchMap((files) => {
          if (files.length) {
            return of(files[0]);
          }
          return throwError(() => new createError.NotFound());
        })
      )
      .subscribe({
        next: (file) => {
          try {
            const readstream = this.gridFsBucket.openDownloadStreamByName(file.filename);
            readstream.pipe(res);
          } catch (error) {
            console.log(error);
            res.json(null);
          }
        },
        error: (err) => {
          handleRouteErrors(err, res, next);
        },
      });
  }

  private creatConnectionGridFs(): void {
    const connection = mongoose.createConnection(`${process.env.MONGODB}`);
    connection.once('open', () => {
      // 初始化原生GridFSBucket,指定集合名为uploads
      this.gridFsBucket = new GridFSBucket(connection.db, {
        bucketName: 'uploads'
      });
    });
  }
}

该方案无第三方依赖兼容问题,长期维护性更好。

内容的提问来源于stack exchange,提问作者Miguel Frias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:15:05