NestJS - 每个模块使用多个 MongoDB 连接

Posted

技术标签:

【中文标题】NestJS - 每个模块使用多个 MongoDB 连接【英文标题】:NestJS - Use multiple MongoDB connections per module 【发布时间】:2020-03-23 07:11:19 【问题描述】:

有没有办法为每个模块连接多个 MongoDB 连接?

app.module.ts

@Module(
  imports: [
    MongooseModule.forRoot('mongodb://localhost/masterDB'),
    UserModule,
  ],
  controllers: [AppController],
  providers: [AppService],
)
export class AppModule  

同样,我们能否在另一个模块中定义另一个连接,它是 app.module 的子模块?

child.module.ts

@Module(
  imports: [
    MongooseModule.forRoot('mongodb://localhost/childDB'),
    MongooseModule.forFeature([ name: 'child', schema: ChildSchema ]),
  ],
  controllers: [ChildController],
  providers: [ChildService],
)
export class ChildModule  

或任何其他方式一次访问不同的数据库。

提前致谢!

【问题讨论】:

【参考方案1】:

您必须手动完成,您必须使用提供程序文件:

mongoose.providers.ts

import * as mongoose from 'mongoose';

export const mongooseProviders = [
  
    provide: 'MASTER_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
    // This mongoose.connect never working for multples DB connection
    // mongoose.connect('mongodb://localhost/masterDB'),
    // Following is working fine and tested by me
    mongoose.createConnection('mongodb://localhost/masterDB'),
  ,
  
    provide: 'CHILD_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
    // This mongoose.connect never working for multples DB connection
    // mongoose.connect('mongodb://localhost/masterDB'),
    // Following is working fine and tested by me
      mongoose.createConnection('mongodb://localhost/ChildDB'),
  ,
];

mongoose.module.ts

import  Module  from '@nestjs/common';
import  mongooseProviders  from './mongoose.providers';

@Module(
  providers: [...mongooseProviders],
  exports: [...mongooseProviders],
)
export class MongooseModule 

model.providers.ts

import  Connection  from 'mongoose';
import  ChildSchema  from './schemas/child/child.schema';
import  MasterSchema  from './schemas/master/master.schema';

export const modelProviders = [
  
    provide: 'CHILD_MODEL',
    useFactory: (connection: Connection) => connection.model('Child', ChildSchema),
    inject: ['CHILD_CONNECTION'],
  ,
  
    provide: 'MASTER_MODEL',
    useFactory: (connection: Connection) => connection.model('Master', MasterSchema),
    inject: ['MASTER_CONNECTION'],
  ,
];

并且在构造函数上而不是使用@InjectModel 你使用@Inject:

@Injectable
export Class ModelService 
  constructor(@Inject('MASTER_MODEL') private masterModel: Model<Master>) 
...

注意:在您提供服务的模块中,您应该导入 MongooseModule 并作为提供者 modelProviders。

【讨论】:

嗨,这似乎是问题的正确答案,我将其标记为“已回答”。但是这些提供者是单身人士,对吧?我们可以有一个动态连接名称吗?例如我可能有多个动态子(租户)数据库——childDB1、childDB2、childDB3 ...等等。 是的,您可以为每个连接使用自定义提供程序docs.nestjs.com/fundamentals/custom-providers 看看这个 嘿,我认为我上面的评论不清楚。我有一种情况 - 我的 MasterDB 中有用户集合,并且对于在应用程序中注册的每个用户,我需要动态创建和使用 ChildDB,例如MasterDB 中的 user1 将拥有自己的 user1DB,只能由某些特定模块访问。如何更新每个模块的 MongoDB uri? 只需在其工厂的 mongoose.providers.ts 中更改它【参考方案2】:

上面来自 RalphJS 的帖子确实有帮助,但它只使用一个连接来处理所有事情。必须更改 model.providers.ts 中的 1 件事: 而不是mongoose.connect 你必须使用mongoose.createConnection

model.providers.ts

import * as mongoose from 'mongoose';

export const mongooseProviders = [
  
    provide: 'MASTER_CONNECTION',
    useFactory: async (): Promise<unknown> =>
      await mongoose.createConnection('mongodb://localhost/masterDB'),
  ,
  
    provide: 'CHILD_CONNECTION',
    useFactory: async (): Promise<unknown> =>
      await mongoose.createConnection('mongodb://localhost/childDB'),
  ,
];

https://mongoosejs.com/docs/connections.html#multiple_connections

【讨论】:

【参考方案3】:

[2021 年 3 月解决]

您会在这里找到解决方案:

https://www.learmoreseekmore.com/2020/04/nestjs-multiple-mongodb-databases.html

import  Module  from '@nestjs/common';
import  MongooseModule  from '@nestjs/mongoose';
import  studentSchema  from './schemas/myworld/student.schema';
import  animalSchema  from './schemas/wildlife/animal.schema';

@Module(
  imports: [
    MongooseModule.forFeature([
      
        name: 'Student',
        schema: studentSchema,
        collection: 'Student',
        
      ,
    ],'myWorldDb'),
    MongooseModule.forFeature([
      
        name: 'Animals',
        schema: animalSchema,
        collection: 'Animals'
      
    ],'wildLifeDb'),
    MongooseModule.forRoot(
      'mongodb+srv://<userName>:<password>@cluster0-igk.mongodb.net/MyWorld?retryWrites=true&w=majority',
      
        connectionName: 'myWorldDb'
      
    ),
    MongooseModule.forRoot(
      'mongodb+srv://<username>:<password>@cluster0-igk.mongodb.net/WildLife?retryWrites=true&w=majority',
      
        connectionName: 'wildLifeDb'
      
    )

  ],
  controllers: [],
  providers: [],
)
export class AppModule 

【讨论】:

以上是关于NestJS - 每个模块使用多个 MongoDB 连接的主要内容,如果未能解决你的问题,请参考以下文章

带有nestjs的Angular-universal:错误:找不到模块'./drivers/node-mongodb-native/connection'

通过库共享时未注册 NestJS 自定义 PassportStrategy

mongodb/mongoose:如果来自nestjs的数据不为空,则保存唯一值

使用 Nestjs/Angular 初始化 MongoDB 时出错

如何在 NestJS 中跨模块全局注入价值?

NestJS - 如何自我引用 mongoDB 架构 @nestjs/mongoose?