Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs Menu
Docs Home
/ / /
Node.js ドライバー
/

チュートリアル: Mongooseを使い始める

Mongooseは、 MongoDBのオブジェクト データ モデリング(ODM)ライブラリです。Mongooseを使用して、データ モデリング、スキーマの適用、モデル検証、一般的なデータ操作に役立ちます。MongoDB には、将来データベースを変更および更新できる柔軟なデータモデルがあるため、固定スキーマはありません。ただし、 Mongoose は最初から半固定的なスキーマを強制するため、スキーマとモデルを定義する必要があります。

スキーマは、コレクションドキュメントの構造を定義します。MongooseスキーマはMongoDBコレクションに直接マッピングします。

次の例では、blog という名前の新しいスキーマを作成します。

const blog = new Schema({
title: String,
slug: String,
published: Boolean,
author: String,
content: String,
tags: [String],
comments: [{
user: String,
content: String,
votes: Number
}]
}, {
timestamps: true
});

スキーマを作成するときは、各フィールドとそのデータ型を定義する必要があります。次のタイプが許可されます。

  • 文字列

  • 番号

  • 日付

  • Buffer

  • ブール値

  • 混合

  • ObjectId

  • 配列

  • Int32

  • Decimal128

  • Double

  • Map

モデルはスキーマを受け取り、コレクション内の各ドキュメントにそれを適用します。モデルは、作成、読み取り、更新、削除( CRUD )操作など、すべてのドキュメントインタラクションを担当します。

Tip

モデルに渡す最初の引数は、コレクション名の単数形です。Mongoose はこれを自動的に複数形に変更し、小文字に変換し、それをデータベースコレクション名に使用します。

次の例は、blogスキーマを使用する Blog という名前のモデルを宣言する方法を示しています。

const Blog = mongoose.model('Blog', blog);

前の例では、Blog はMongoDBの blogsコレクションに変換されています。

このチュートリアルでは、次のアクションを実行します。

  • Mongooseを使用するために環境を設定する

  • MongoDB に接続する

  • Mongoose のスキーマとモデルを作成する

  • データの挿入、更新、検索、削除

  • プロジェクトドキュメントフィールド

  • データを検証する

  • 複数のスキーマとミドルウェアの使用

1

このチュートリアルを開始する前に、次のコンポーネントが準備されていることを確認してください。

  • 構成されたクラスターを持つMongoDB Atlasアカウント。手順を表示するには、「 Atlas を使い始める」ガイドを参照してください。

  • Node.js v16.20.1以降に更新します。

2

このチュートリアルでは、 Nodemon を使用してコードをローカルで実行します。プロジェクトを初期化し、必要な依存関係をインストールするには、ターミナルで次のコマンドを実行します。

mkdir mongodb-mongoose
cd mongodb-mongoose
npm init -y
npm i mongoose
npm i -D nodemon

希望のコード エディターでプロジェクトを開きます。このチュートリアルでは、CommonJS ではなく ES モジュールを使用します。ES モジュールを使用するには、module タイプを追加する必要があります。package.jsonファイルにGo、次のコードを追加します。

...
"scripts": {
"dev": "nodemon index.js"
},
"type": "module",
...

次のコマンドを実行中て、nodemon でアプリケーションを起動します。

npm run dev

注意

Nodemon を使用すると、ファイルを保存するたびにコードが実行されます。

3

プロジェクトのルート レベルで、index.js という名前のファイルを作成し、ファイルの先頭に次のコードを追加します。

import mongoose from 'mongoose';
mongoose.connect("<connection string>")

<connection string> プレースホルダーをMongoDB Atlas接続文字列に置き換えます。 接続文字列を見つける方法の詳細については、Atlas ドキュメントの「クラスターへの接続」チュートリアルを参照してください。

4

MongoDBでデータの追加と更新を開始する前に、スキーマとモデルを作成する 必要があります。

Mongooseでは、必要なスキーマごとにスキーマモデルファイルを作成します。まず、すべてのスキーマファイルを格納するための model というフォルダーを作成し、次に Blog.js という最初のスキーマファイルを作成します。このファイルを開き、次のコードを追加します。

import mongoose from 'mongoose';
const { Schema, model } = mongoose;
const blogSchema = new Schema({
title: String,
slug: String,
published: Boolean,
author: String,
content: String,
tags: [String],
comments: [{
user: String,
content: String,
votes: Number
}]
}, {
timestamps: true
});
const Blog = model('Blog', blogSchema);
export default Blog;

このスキーマでは timestamps オプションが有効になります。これにより、自動的に更新される mongoose が管理する createdAt フィールドと updatedAt フィールドがスキーマに追加されます。詳細については、 Mongooseドキュメントのタイムスタンプページを参照してください。

5

これで最初のモデルとスキーマが設定され、データベースへのデータの挿入を開始できます。次のセクションでは、 Mongooseを使用してCRUD操作を実行する方法を説明します。

index.js にGo、ファイルの先頭に次のインポート ステートメントを追加します。

import Blog from './model/Blog.js';

接続文字列を含む行の下に次のコードを追加します。

// Creates a new blog post and inserts it into database
const article = await Blog.create({
title: 'Awesome Post!',
slug: 'awesome-post',
published: true,
content: 'This is the best post ever',
tags: ['featured', 'announcement'],
});
console.log('Created article:', article);

上記のコードでは、 Mongoose create() メソッドを使用してブログ記事を表すオブジェクトをインスタンス化し、それをデータベースに保存します。返されたドキュメントは、_id を含むコンソールにログを記録します。この _id をメモしておき、後の手順で使用します。

データを更新するには、 Mongooseを使用してローカルオブジェクトを直接編集します。次に、save() メソッドを使用してアップデートをデータベースに書込み (write) ます。

前のセクションに挿入した記事をアップデートするには、次のコードを追加します。

// Updates the title of the article
article.title = "The Most Awesomest Post!!";
await article.save();
console.log('Updated Article:', article);
Updated Article: {
title: 'The Most Awesomest Post!!',
slug: 'awesome-post',
published: true,
content: 'This is the best post ever',
tags: [ 'featured', 'announcement' ],
_id: new ObjectId('...'),
comments: [],
__v: 0
}

特定のドキュメントを検索するには、 Mongoose findById() メソッドを使用してドキュメントをクエリし、ドキュメントの _id を指定します。

次のコードを index.jsファイルに追加して、_id で特定の記事を検索します。

// Finds the article by its ID. Replace <object id> with the objectId of the article.
const articleFound = await Blog.findById("<object id>").exec();
console.log('Found Article by ID:', articleFound);
Found Article by ID: {
_id: new ObjectId('68261c9dae39e390341c367c'),
title: 'The Most Awesomest Post!!',
slug: 'awesome-post',
published: true,
content: 'This is the best post ever',
tags: [ 'featured', 'announcement' ],
comments: [],
__v: 0
}

注意

デフォルトでは 、 MongooseクエリはJavaScript Promise の一部のプロパティを持つオブジェクトである whenables を返します。true JavaScript Promise を受け取るには、クエリに exec() メソッドを追加します。 Mongooseでの Promise の操作の詳細については、 Mongooseドキュメントの Promiseガイド を参照してください。

Mongooseを使用して、必要なフィールドのみをプロジェクトできます。次のコードでは、 を指定して、titleslugcontent フィールドのみをプロジェクト。

次のコードを index.jsファイルに追加し、<object id> プレースドキュメントを ObjectId 値に置き換えます。

// Finds the article by its ID and projects only the title, slug, and content fields.
// Replace <object id> with the objectId of the article.
const articleProject = await Blog.findById("<object id>", "title slug content").exec();
console.log('Projected Article:', articleProject);
Projected Article: {
_id: new ObjectId('...'),
title: 'The Most Awesomest Post!!',
slug: 'awesome-post',
content: 'This is the best post ever'
}

Mongoose は、deleteOne() メソッドと deleteMany() メソッドを使用して、コレクションからデータを削除します。削除するドキュメントのフィールドを指定し、そのフィールドを選択した方法に渡すことができます。

次のコードをインデックスの.jsファイルに追加して、データベースから 1 つの記事を削除します。

// Deletes one article with the slug "awesome-post".
const blogOne = await Blog.deleteOne({ slug: "awesome-post" });
console.log('Deleted One Blog:', blogOne);
Deleted One Blog: { acknowledged: true, deletedCount: 1 }

複数の記事を削除するには、次のコードを追加します。

// Deletes all articles with the slug "awesome-post".
const blogMany = await Blog.deleteMany({ slug: "awesome-post" });
console.log('Deleted Many Blogs:', blogMany);
Deleted Many Blogs: { acknowledged: true, deletedCount: 4 }
6

前の手順で挿入された記事には、authordates、または comments フィールドは含まれていません。これらのフィールドはスキーマに含まれているにもかかわらず、これは、ドキュメントの構造を定義しましたが、どのフィールドが必須であるかを定義していないためです。必須として定義されていないフィールドは省略できます。

Mongooseでは、フィールドの検証を含める場合、その値としてオブジェクトを渡す必要があります。

注意

バリデーターは create() メソッドと save() メソッドで自動的に実行されます。runValidators オプションを true に設定することで、update()updateOne() などの更新メソッドでこれらを指定して実行できます。バリデーターの詳細については、 Mongooseドキュメントの検証ページを参照してください。

Mongooseではいくつかの検証メソッドを使用できます。例、必要なフィールドで required を true に設定できます。型と形式を検証することもできます。次のコードでは、slugフィールドは、minLength4 である string として定義されています。つまり、4 文字未満の slug を提供すると ValidationError が生成されます。

データ検証を追加し、これらの要件を定義するには、次の例に示すように、Blog.js のスキーマを更新します。

const blogSchema = new Schema({
title: {
type: String,
required: true,
},
slug: {
type: String,
required: true,
minLength: 4,
},
published: {
type: Boolean,
default: false,
},
author: {
type: String,
required: true,
},
content: String,
tags: [String],
comments: [{
user: String,
content: String,
votes: Number
}]
}, {
timestamps: true
});

この検証を追加すると、アプリケーションがクラッシュします。新しい検証要件を満たすには、index.jsファイルの create() 呼び出しに authorフィールドを追加します。

// Creates a new blog post and inserts it into database
const article = await Blog.create({
title: 'Awesome Post!',
slug: 'awesome-post',
published: true,
author: 'A.B. Cee',
content: 'This is the best post ever',
tags: ['featured', 'announcement'],
});

Tip

Mongooseでスキーマを使用する場合、value: Stringvalue: {type: String} と同じになります。

詳細については、 Mongooseドキュメントの「検証」ページを参照してください。

7

次に、別のスキーマを作成し、それを ブログスキーマにネストすることで、authorフィールドの複雑度を高めることができます。

model フォルダーに User.js という名前の新しいファイルを作成します。このファイルに次のコードを追加します。

import mongoose from 'mongoose';
const {Schema, model} = mongoose;
const userSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
minLength: 10,
required: true,
lowercase: true
},
});
const User = model('User', userSchema);
export default User;

新しいユーザー モデルを使用してブログスキーマの authorフィールドを定義するには、Blog.jsファイルを次の変更で更新します。

  • Mongooseライブラリから抽出されたプロパティのリストに SchemaTypes を追加します。

  • authorフィールドtypeSchemaTypes.ObjectId に変更し、'User' モデルに参照(ref)を追加します。

次のコードは、これらの更新を示しています。

const { Schema, SchemaTypes, model } = mongoose;
... // Inside Schema block:
author: {
type: SchemaTypes.ObjectId,
ref: 'User',
required: true,
},
...

blogSchema の定義を変更することで、comment.userフィールドで同じ User モデルを再利用できます。

... // Inside Schema block:
comments: [{
user: {
type: SchemaTypes.ObjectId,
ref: 'User',
required: true,
},
...

アプリケーションで新しいユーザーモデルを使用するには、 index.jsファイルにGo。 ユーザー モデルをインポートするには、ファイルの先頭に次のコードを追加します。

import User from './model/User.js';

ブログスキーマにフィールド検証を追加したため、ブログを挿入、更新、削除し、プロジェクトのフィールドを指定する前のコードは検証に合格せず、アプリケーションはエラーになります。

次の create() 呼び出しを追加して、新しいユーザーを作成します。

// Create a new user
const user = await User.create({
name: 'Jess Garica',
email: 'jgarcia@email.com',
});

次のコードで既存の create() 呼び出しを更新し、次のコードに示すように、新しいユーザーを著者として使用する新しい記事を作成します。

// Creates a new blog post that references the user as the author
const articleAuthor = await Blog.create({
title: 'Awesome Post!',
slug: 'Awesome-Post',
author: user._id,
content: 'This is the best post ever',
tags: ['featured', 'announcement'],
});
console.log('Article with Author:', articleAuthor);
Article with Author: {
title: 'Awesome Post!',
slug: 'awesome-post',
published: false,
author: new ObjectId('...'),
content: 'This is the best post ever',
tags: [ 'featured', 'announcement' ],
_id: new ObjectId('...'),
createdAt: 2025-05-15T18:05:23.780Z,
comments: [],
__v: 0
}

上記のコードでは、 MongoDBデータベースに blogsコレクションを持つ usersコレクションが追加されます。このコードは、必要な authorフィールドを追加し、その値を user._id に設定します。

記事の authorフィールドに name フィールドと email フィールドの値を追加するには、 Mongoose populate() メソッドをブログ クエリに追加します。populate() メソッドは、user._id が参照するユーザードキュメントに対して 2 番目のクエリを実行します。

このデータを入力するには、次のコードを index.js に追加します。

// Populates the author field with user data
const articlePopulate = await Blog.findOne({ title: "Awesome Post!" }).populate("author");
console.log('Article Populated:', articlePopulate);
Article Populated: {
_id: new ObjectId('...'),
title: 'Awesome Post!',
slug: 'awesome-post',
published: false,
author: {
_id: new ObjectId('...'),
name: 'Jess Garica',
email: 'jgarcia@email.com',
__v: 0
},
content: 'This is the best post ever',
tags: [ 'featured', 'announcement' ],
createdAt: 2025-05-15T18:04:28.590Z,
comments: [],
__v: 0
}

詳細については、 Document.popify() のMongoose APIドキュメントのページを参照してください。

8

Mongooseでは、ミドルウェアはスキーマレベルで非同期関数の実行の前または実行中に実行される関数です。

ミドルウェアの例は、保存または更新する前に Userインスタンスの emailフィールドを検証する関数が挙げられます。

この例ではvalidatorパッケージを使用します。validatorパッケージは、次のコマンドを実行中てインストールできます。

npm install validator

このミドルウェア関数を追加するには、User.jsファイルの userSchema 宣言に次のコードを追加します。

import validator from 'validator';
userSchema.pre('save', function (next) {
const user = this;
// Normalize email
if (user.email) {
user.email = user.email.trim().toLowerCase();
}
// Validate email format
if (!validator.isEmail(user.email)) {
return next(new Error('Invalid email format'));
}
next();
});

この関数の効果を確認するには、index.jsファイルの user.emailフィールドを変更して無効なメールアドレスにします。

const user = await User.create({
name: 'Jess Garica',
email: 'jgarciaemail.com',
});
Error: Invalid email format

メールアドレスを修正すると、エラーがスローされないことが確認できます。

pre()ミドルウェア関数に加えて、 Mongoose はpost() ミドルウェア関数も提供しています。ミドルウェアの詳細については、 Mongooseドキュメントの「 ミドルウェア 」のページを参照してください。

これで、 Mongooseを使用してMongoDBコレクションでCRUD操作を実行するサンプルプロジェクトができました。ここから、より複雑なクエリまたはドキュメント検証を使用して、このプロジェクトに を構築することを選択できます。次のセクションには、アプリケーションで使用可能なMongoose機能の例がいくつか含まれています。

カスタム セッターは保存時にデータを変更し、バリデーターと同様に実装できます。Mongoose は、次のカスタム セッターを提供します。

  • lowercase

  • uppercase

  • trim

次の例では、blog.slugフィールドの文字を小文字にします。

const blogSchema = new Schema({
...
slug: {
type: String,
required: true,
minLength: 4,
lowercase: true,
},
...
});

詳細については、 Mongoose APIドキュメントの「SchemaStringOptions」ページを参照してください。

Mongoose には、通常のMongoDBメソッドから抽象化されたいくつかのヘルパーメソッドが含まれています。このセクションでは、これらのメソッドの一部の例を見つけることができます。これらのメソッドはこのチュートリアルでは特に使用されませんが、 Mongooseを使い始めるときに参照のに役立ちます。

exists() メソッドは、null または指定されたクエリに一致する最初のドキュメントのいずれかを返します。以下は、authorフィールドに基づいて記事を一致させる例です。

const blog = await Blog.exists({ author: 'Jess Garcia' });
console.log(blog);

詳細については、Model.exists() のMongoose APIドキュメントの「」セクションを参照してください。

where() メソッドを使用すると、複雑なクエリを連鎖して構築できます。

次の例では、findOne() をプレーン クエリオブジェクトと、where() メソッドによる同等のクエリで使用して検索操作を実行します。

const blogFind = await Blog.findOne({ author: "Jess Garcia" });
console.log(blogFind);
const blogWhere = await Blog.findOne().where("author").equals("Jess Garcia");
console.log(blogWhere);

この実装では、where() の実装はfindOne() で始まり、これはMongoose にそれを findOne() クエリとして扱うように指示します。これは重要です。where() を単独(Blog.where(...))で使用すると、 Mongoose はそれを暗黙的に find()操作として扱うため、

一般的に、where() メソッドは、動的クエリ構築や複数のコンパラメータを含む複雑なクエリに使用されます。また、このメソッドを使用すると読みやすさが向上します。where() メソッドを使用することも、通常のオブジェクトクエリを使用することもパフォーマンスに違いはありません。

where() メソッドを使用するときにプロジェクションを含めるには、次の例に示すように、クエリの後に select() メソッドを連鎖させます。

const blog = await Blog.findOne().where("author").equals("Jess Garcia").select("title author");
console.log(blog);

詳細については、 Mongoose APIドキュメントの次のセクションを参照してください。

MongoDBでMongooseを使用する方法の詳細については、 Mongoose のドキュメント を参照してください。

MongoDB Community に貢献したりするには、MongoDB Developer Community ページを参照してください。

戻る

サードパーティ統合

項目一覧