Ank
Ank

Reputation: 178

NestJS - Use multiple MongoDB connections per module

Is there a way to connect multiple MongoDB connections per module?

app.module.ts

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

Similarly, can we define another connection in another module which is a child of 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 { }

Or any other way to access different databases at once.

Thanks in advance!

Upvotes: 3

Views: 14432

Answers (3)

RalphJS
RalphJS

Reputation: 533

You have to do it manually you have to use a providers file:

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'],
  },
];

And on the constructor instead of using @InjectModel you use @Inject:

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

Note: in the module you provide the service you should import the MongooseModule and put as provider modelProviders.

Upvotes: 8

Despertaweb
Despertaweb

Reputation: 1820

[SOLVED March 2021]

Here you'll find the solution:

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 {}

Upvotes: 12

Sairys
Sairys

Reputation: 41

Post above from RalphJS really helped, but it only was using one connection for everything. Had to change 1 thing in model.providers.ts: instead of mongoose.connect you have to use 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

Upvotes: 4

Related Questions