@nestjs/mongoose Documentation

repository·master·Indexed 20 days ago

https://github.com/nestjs/mongoose

The official NestJS module for integrating Mongoose and MongoDB. It provides decorators like @Schema, @Prop, and @Virtual for defining schemas, as well as @InjectModel and @InjectConnection for dependency injection. Includes utilities for schema generation via SchemaFactory.createForClass and configuration options for both synchronous and asynchronous module initialization using MongooseModule.

Tokens
4.4K
Snippets
21
Records
23
Agent score
69%

What's inside @nestjs/mongoose

  1. Retrieve a connection token with getConnectionToken()

    master

    Use getConnectionToken(name?) to generate the injection token for a specific Mongoose connection.

    • If name is provided and is not the DEFAULT_DB_CONNECTION, it returns ${name}Connection.
    • If name is undefined or matches the DEFAULT_DB_CONNECTION, it returns the DEFAULT_DB_CONNECTION token.
    import { getConnectionToken } from '@nestjs/mongoose';
    
    // For the default connection
    const defaultToken = getConnectionToken();
    
    // For a specific named connection
    const customToken = getConnectionToken('tenant1'); // returns 'tenant1Connection'
  2. Define a Mongoose schema using the @Schema decorator

    master

    Use the @Schema() decorator to mark a class as a Mongoose schema. This decorator registers the class with the internal metadata storage so NestJS can manage it as a Mongoose schema.

    Important: Only properties that are explicitly decorated (typically with @Prop(), though not shown in this specific file) will be included in the resulting Mongoose schema. The @Schema() decorator itself accepts an optional SchemaOptions object, which is compatible with standard mongoose.SchemaOptions.

    import { Schema } from '@nestjs/mongoose';
    import { mongoose } from 'mongoose';
    
    @Schema({ timestamps: true })
    class User {
      // properties go here
    }
  3. Retrieve a model token with getModelToken()

    master

    Use getModelToken(model, connectionName?) to generate the unique injection token required to inject a Mongoose model into a NestJS provider.

    • If connectionName is not provided, it returns ${model}Model.
    • If a connectionName is provided, it returns ${getConnectionToken(connectionName)}/${model}Model to ensure the model is associated with the correct connection.
    import { getModelToken } from '@nestjs/mongoose';
    
    // For the default connection
    const token = getModelToken('User'); // returns 'UserModel'
    
    // For a specific named connection
    const tokenWithConn = getModelToken('User', 'tenant1'); // returns 'tenant1Connection/UserModel'
  4. Configure Mongoose connection asynchronously with forRootAsync()

    master

    Use MongooseModule.forRootAsync() when you need to configure the Mongoose connection using values that are not available at compile time, such as those retrieved from a configuration service or environment variables. It accepts MongooseModuleAsyncOptions.

    @Module({
      imports: [
        MongooseModule.forRootAsync({
          useFactory: async () => ({
            uri: 'mongodb://localhost/myapp',
          }),
        }),
      ],
    })
    export class AppModule {}
  5. Define schema properties with the @Prop decorator

    master

    The @Prop() decorator is used to mark specific class properties as Mongoose schema properties. Only properties decorated with @Prop() will be included in the generated Mongoose schema.

    If you do not provide a type in the options, the decorator attempts to infer the type from the TypeScript metadata. If the type cannot be determined (e.g., for plain Object types or when metadata is missing), it will throw a CannotDetermineTypeError.

    Supported options for @Prop() include:

    • A partial mongoose.SchemaDefinitionProperty object.
    • A mongoose.SchemaType.
    • A raw object definition (using the RAW_OBJECT_DEFINITION constant).
    import { Prop } from '@nestjs/mongoose';
    
    class User {
      @Prop({ required: true })
      name: string;
    
      @Prop({ type: String, default: 'Guest' })
      role: string;
    
      @Prop([String])
      tags: string[];
    }
  6. Register Mongoose models with forFeature()

    master

    Use MongooseModule.forFeature() to register specific Mongoose models within a feature module. This makes the models available as injectable providers within that module and its dependents. You can optionally specify a connectionName if you are working with multiple database connections.

    @Module({
      imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
    })
    export class UsersModule {}
  7. Configure MongooseModule with MongooseModuleOptions

    master

    When initializing the MongooseModule synchronously, use the MongooseModuleOptions interface. This interface extends Mongoose's ConnectOptions and adds NestJS-specific configuration for connection management, retries, and lifecycle hooks.

    Key properties include:

    • uri: The MongoDB connection string.
    • retryAttempts: Number of times to attempt reconnection.
    • retryDelay: Delay between reconnection attempts.
    • connectionName: A unique name for the connection (useful for multiple connections).
    • lazyConnection: If true, the connection is not established until the first model is used.
    • onConnectionCreate: A callback function triggered when a connection is successfully created.
    • connectionErrorFactory: A function to transform or handle MongooseError during connection failures.
    • verboseRetryLog: If true, logs detailed error messages during retry attempts.
    // Example of synchronous configuration
    MongooseModule.forRoot({
      uri: 'mongodb://localhost/nest',
      retryAttempts: 3,
      retryDelay: 5000,
      connectionName: 'my-connection',
    });
  8. Register Mongoose models asynchronously with forFeatureAsync()

    master

    Use MongooseModule.forFeatureAsync() to register Mongoose models using asynchronous factories. This is useful when model definitions depend on other providers or configuration. It accepts an array of AsyncModelFactory objects and an optional connectionName.

    @Module({
      imports: [
        MongooseModule.forFeatureAsync([
          {
            useFactory: async (configService: ConfigService) => ({
              name: User.name,
              schema: UserSchema,
            }),
            inject: [ConfigService],
          },
        ]),
      ],
    })
    export class UsersModule {}
  9. Define a Mongoose model with discriminators

    master

    When using MongooseModule.forFeature(), you can provide a ModelDefinition object to define your models. If your model uses inheritance, you can include a discriminators array to define sub-types.

    Each entry in the discriminators array must be a DiscriminatorOptions object containing:

    • name: The name of the discriminator.
    • schema: The Mongoose Schema for the discriminator.
    • value (optional): The value used to identify the discriminator in the database.
    import { Schema } from 'mongoose';
    import { ModelDefinition, DiscriminatorOptions } from '@nestjs/mongoose';
    
    const modelDefinition: ModelDefinition = {
      name: 'User',
      schema: new Schema({ name: String }),
      discriminators: [
        {
          name: 'Admin',
          schema: new Schema({ privileges: [String] }),
          value: 'admin_type',
        },
      ],
    };
  10. Configure MongooseModule asynchronously with MongooseModuleAsyncOptions

    master

    To configure the MongooseModule asynchronously (e.g., when options depend on other services or environment variables), use MongooseModuleAsyncOptions. This is typically used with MongooseModule.forRootAsync().

    You can provide options using one of three patterns:

    1. useFactory: A function that returns MongooseModuleFactoryOptions. You can use inject to provide dependencies to this factory.
    2. useClass: A class that implements the MongooseOptionsFactory interface.
    3. useExisting: An existing provider that implements the MongooseOptionsFactory interface.

    Note: When using useFactory, the returned object must be of type MongooseModuleFactoryOptions, which is MongooseModuleOptions excluding the connectionName property (as connectionName is specified at the module level).

    // Example using useFactory with injection
    MongooseModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        uri: configService.get('MONGODB_URI'),
        retryAttempts: 5,
      }),
    });