モデル

モデルは、Schema定義からコンパイルされた高度なコンストラクタです。モデルのインスタンスはドキュメントと呼ばれます。モデルは、基盤となる MongoDB データベースとの間でドキュメントを作成および読み取る役割を担います。

最初のモデルをコンパイルする

スキーマでmongoose.model()を呼び出すと、Mongoose はモデルをコンパイルします。

const schema = new mongoose.Schema({ name: String, size: String });
const Tank = mongoose.model('Tank', schema);

最初の引数は、モデルが対象とするコレクションの単数名です。Mongoose は、モデル名の複数形、小文字バージョンを自動的に探します。したがって、上記の例では、モデル Tank はデータベース内の tanks コレクションを対象としています。

注:.model() 関数は、schema のコピーを作成します。.model() を呼び出す前に、フックなど、schema に必要なものをすべて追加したことを確認してください!

ドキュメントの構築

モデルのインスタンスは、ドキュメントと呼ばれます。それらを作成してデータベースに保存するのは簡単です。

const Tank = mongoose.model('Tank', yourSchema);

const small = new Tank({ size: 'small' });
await small.save();

// or

await Tank.create({ size: 'small' });

// or, for inserting large batches of documents
await Tank.insertMany([{ size: 'small' }]);

モデルが使用する接続が開かれるまで、タンクは作成/削除されないことに注意してください。すべてのモデルには、関連付けられた接続があります。mongoose.model() を使用すると、モデルはデフォルトの mongoose 接続を使用します。

await mongoose.connect('mongodb://127.0.0.1/gettingstarted');

カスタム接続を作成する場合は、代わりにその接続の model() 関数を使用してください。

const connection = mongoose.createConnection('mongodb://127.0.0.1:27017/test');
const Tank = connection.model('Tank', yourSchema);

クエリ

ドキュメントの検索は、MongoDB の豊富なクエリ構文をサポートする Mongoose で簡単に行えます。ドキュメントは、modelfindfindByIdfindOne、またはwhere静的関数を使用して取得できます。

await Tank.find({ size: 'small' }).where('createdDate').gt(oneYearAgo).exec();

クエリの章で、Query API の使用方法の詳細をご覧ください。

削除

モデルには、指定された filter に一致するすべてのドキュメントを削除するための静的な deleteOne() および deleteMany() 関数があります。

await Tank.deleteOne({ size: 'large' });

更新

model には、データベース内のドキュメントをアプリケーションに返すことなく変更するための独自の update メソッドがあります。詳細については、APIドキュメントを参照してください。

// Updated at most one doc, `res.nModified` contains the number
// of docs that MongoDB updated
await Tank.updateOne({ size: 'large' }, { name: 'T-90' });

データベース内の単一のドキュメントを更新してアプリケーションに返す場合は、代わりにfindOneAndUpdateを使用してください。

変更ストリーム

変更ストリームは、MongoDB データベースを通過するすべての挿入と更新をリッスンする方法を提供します。変更ストリームは、MongoDB レプリカセットに接続していない限り、機能しないことに注意してください。

async function run() {
  // Create a new mongoose model
  const personSchema = new mongoose.Schema({
    name: String
  });
  const Person = mongoose.model('Person', personSchema);

  // Create a change stream. The 'change' event gets emitted when there's a
  // change in the database
  Person.watch().
    on('change', data => console.log(new Date(), data));

  // Insert a doc, will trigger the change stream handler above
  console.log(new Date(), 'Inserting doc');
  await Person.create({ name: 'Axl Rose' });
}

上記の非同期関数からの出力は、以下に示すようなものになります。

2018-05-11T15:05:35.467Z 'ドキュメントを挿入中' 2018-05-11T15:05:35.487Z 'ドキュメントを挿入済み' 2018-05-11T15:05:35.491Z { _id: { _data: ... }, operationType: 'insert', fullDocument: { _id: 5af5b13fe526027666c6bf83, name: 'Axl Rose', __v: 0 }, ns: { db: 'test', coll: 'Person' }, documentKey: { _id: 5af5b13fe526027666c6bf83 } }

このブログ記事で、Mongoose での変更ストリームの詳細をご覧ください。

ビュー

MongoDB ビューは、基本的に読み取り専用のコレクションであり、集計を使用して他のコレクションから計算されたデータが含まれています。Mongoose では、ビューごとに個別のモデルを定義する必要があります。createCollection() を使用してビューを作成することもできます。

次の例は、名前や電子メールなどの機密性の高い可能性のある情報を非表示にする、User モデルで新しい RedactedUser ビューを作成する方法を示しています。

// Make sure to disable `autoCreate` and `autoIndex` for Views,
// because you want to create the collection manually.
const userSchema = new Schema({
  name: String,
  email: String,
  roles: [String]
}, { autoCreate: false, autoIndex: false });
const User = mongoose.model('User', userSchema);

const RedactedUser = mongoose.model('RedactedUser', userSchema);

// First, create the User model's underlying collection...
await User.createCollection();
// Then create the `RedactedUser` model's underlying collection
// as a View.
await RedactedUser.createCollection({
  viewOn: 'users', // Set `viewOn` to the collection name, **not** model name.
  pipeline: [
    {
      $set: {
        name: { $concat: [{ $substr: ['$name', 0, 3] }, '...'] },
        email: { $concat: [{ $substr: ['$email', 0, 3] }, '...'] }
      }
    }
  ]
});

await User.create([
  { name: 'John Smith', email: 'john.smith@gmail.com', roles: ['user'] },
  { name: 'Bill James', email: 'bill@acme.co', roles: ['user', 'admin'] }
]);

// [{ _id: ..., name: 'Bil...', email: 'bil...', roles: ['user', 'admin'] }]
console.log(await RedactedUser.find({ roles: 'admin' }));

Mongoose は現在、ビューが読み取り専用であることを強制していないことに注意してください。ビューからドキュメントを save() しようとすると、MongoDB サーバーからエラーが返されます。

さらに詳しく

API ドキュメントには、countmapReduceaggregateなど、利用可能な多くの追加メソッドが記載されています。

次に

Modelsについて説明したので、次にドキュメントを見てみましょう。