首页 > 解决方案 > NestJs/Mongoose 中的自动增量序列

问题描述

我正在将 NodeJs 项目迁移到 NestJs,该项目使用 MongoDB 作为后端数据库,使用 Mongoose 作为 ODM。我正在使用mongoose-sequence插件来处理自动增量序列,但是我遇到了需要 NestJs 下的库的麻烦。

mongoose-sequence 文档解释了如何使用 CommonJS 语法导入库,如下所示:

const mongoose = require('mongoose')
const AutoIncrementFactory = require('mongoose-sequence');

const connection = await mongoose.createConnection('mongodb://...');

const AutoIncrement = AutoIncrementFactory(connection);

使用 ES6 导入语法它会是这样的:

import * as mongoose from 'mongoose';
import * as AutoIncrementFactory from 'mongoose-sequence';

const connection = ...;

const AutoIncrement = AutoIncrementFactory(connection);

然而,由于 NestJs 使用依赖注入,访问本机连接并不是那么直接。根据使用 Mongoose 集成 MongoDB 的文档,可以使用以下@InjectConnection()装饰器访问本机 Mongoose Connection 对象:

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private connection: Connection) {}
}

但是由于TypeScript 装饰器只能附加到类声明、方法、访问器、属性或参数,我看不到如何注入连接,需要插件并在我的 Schema 类上初始化它。

标签: node.jsmongodbmongoosenestjsmongoose-sequence

解决方案


可以使用工厂提供程序(即)的forFeatureAsync()方法为给定模式注册插件。MongooseModuleuseFactory

按照官方文档中的示例:

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.plugin(require('mongoose-autopopulate'));
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}

但是对于mongoose-sequence插件,必须将本机 Mongoose 连接对象传递给插件初始化。这可以通过使用以下方法将连接注入工厂提供程序来实现getConnectionToken

import {getConnectionToken, MongooseModule} from '@nestjs/mongoose';
import * as AutoIncrementFactory from 'mongoose-sequence';

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: async (connection: Connection) => {
          const schema = CatsSchema;
          const AutoIncrement = AutoIncrementFactory(connection);
          schema.plugin(AutoIncrement, {inc_field: 'id'});
          return schema;
        },
        inject: [getConnectionToken('YOUR_CONNECTION_NAME')],
      },
    ]),
  ],
})
export class AppModule {}

推荐阅读