🌲
【NestJS】mongooseでクラスとDBのコレクションのフィールド名を分けたい
概要
NestJSでMongoDBに接続する方法として、mongoose
というライブラリを使用するという手段が挙げられます。mongooseの導入方法はこちらのNestJSのドキュメントにあるのですが、Model injection
の項に書いてある実装だと、Schemaのクラスで指定したフィールド名が、そのままDBのコレクションのフィールド名として使われてしまいます。
クラスとDBのフィールド名を、別で管理したいどうするかというのをメモ書きします。
前提など
- NestJSのバージョンは
8.2.6
を使用しています。 - mongooseのバージョンは
6.8.3
を使用しています。 -
nestjs/mongoose
のバージョンは9.2.1
を使用しています。
対応方針
上記の概要で紹介したNestJSのmongooseドキュメントのModel injection
の項の下部に、define a schema manually
の記述があり、schemaのフィールド名を手動で設定することができます。
クラスのフィールド名とどう紐づけるかというと、mongooseのドキュメントAliasesにある通り、schemaにalias
設定を追加することで実現できそうです。
実装サンプル
まずはschemaの設定です。
今回はDBの_id
のaliasとしてobjectId
、user_name
のaliasとしてuserName
を設定しています。
import mongoose, { HydratedDocument } from 'mongoose';
import { v4 as uuidv4 } from 'uuid';
export const USER_ACCOUNT_SCHEMA_NAME = 'user_account';
// DBのスキーマ設定
export const UserAccountSchema = new mongoose.Schema(
{
_id: {
type: String,
alias: 'objectId',
default: uuidv4(),
},
user_name: {
type: String,
required: true,
alias: 'userName',
},
description: {
type: String,
},
},
{ collection: USER_ACCOUNT_SCHEMA_NAME },
);
// データの受け渡しで使用するクラス
export class UserAccountModel {
public objectId?: string;
public userName: string;
public description?: string;
constructor(
userName: string,
description?: string,
objectId?: string,
) {
this.objectId = objectId;
this.userName = userName;
this.description = description;
}
}
export type UserAccountDocument = HydratedDocument<UserAccountModel>;
DBの更新・取得部分の実装です。
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import {
UserAccountDocument,
UserAccountModel,
USER_ACCOUNT_SCHEMA_NAME,
} from '../Model/Mongo/userAccount/userAccount.schema';
@Injectable()
export class UserAccountRepository {
constructor(
@InjectModel(USER_ACCOUNT_SCHEMA_NAME)
private userAccountModel: Model<UserAccountDocument>,
) {}
async createUserAccount(
userName: string,
description?: string,
): Promise<UserAccountModel> {
return await this.userAccountModel.create(
new UserAccountModel(userName, description),
);
}
async findByObjectId(objectId: string): Promise<UserAccountModel> {
// クエリの条件部分はDBのフィールド名で指定する。
return await this.userAccountModel.findOne({ _id: objectId });
}
}
最後にModuleの設定部分の実装です。
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UserAccountRepository } from '../Repository/userAccount.repository';
import {
UserAccountSchema,
USER_ACCOUNT_SCHEMA_NAME,
} from '../Model/Mongo/userAccount/userAccount.schema';
@Module({
imports: [
// スキーマ設定を追加する
MongooseModule.forFeature([
{ name: USER_ACCOUNT_SCHEMA_NAME, schema: UserAccountSchema },
]),
],
controllers: [UserAccountController],
providers: [UserAccountRepository],
})
export class UserAccountModule {}
Discussion