MEANスタック入門(6) MongoDBとの連携

今回はMongoDBのシェルからデータベースを操作する方法と、Node.jsからアクセスする方法についてまとめます。

mongoの使い方とデータベースの作成

ここからはmongoコマンドを使って、MongoDBのシェルで作業していきます。 mongoコマンドを実行すると、MongoDBのシェルに入ります。

$ mongo
データベースの準備

初めにデータベースを作成します。

useコマンドでデータベース名を指定すると、カレントが指定したデータベースに変更になります。 この段階ではsample_dbはまだ追加されず、コレクションやドキュメントを追加した段階で追加されます。

> use sample_db
switched to db sample_db

次に通常のRDBのテーブルにあたる、コレクションを作成します。

> db.createCollection("users")
{ "ok" : 1 }

show collectionsコマンドで実際に作成出来たか確認します。

> show collections
users

最後に、通常のRDBのレコードにあたる、ドキュメントを追加します。

usersコレクションに対して作業するので、dbに続けてdb.usersのようにコレクション名を指定します。 コレクションが存在しなければ、コレクションを新規で作成した上でドキュメントが追加されます。

> db.users.save({id:0, address: "address0"})
WriteResult({ "nInserted" : 1 })

findで実際にドキュメントが追加されたことを確認します。

> db.users.find()
{ "_id" : ObjectId("590dbde126111dfac549518e"), "id" : 0, "address" : "address0" }
(参考)データベースの削除

removeでドキュメントを全削除します。

> db.users.remove({})
WriteResult({ "nRemoved" : 1 })

dropでコレクションごと削除します。

> db.users.drop()
true

dropDatabaseでデータベースごと削除します。

> db.dropDatabase()
{ "dropped" : "sample_db", "ok" : 1 }

show dbsで確認すると、データベース一覧から消えています。

> show dbs
admin      0.000GB
local      0.000GB
ダミーデータの準備

MongoDBのシェルではJavaScriptの構文が使えるので、以下のようなコードを作成してシェルに貼り付けると、まとめてダミーデータが作成出来ます。

use sample_db;
for(let i = 0;i < 20; i++) {
  db.users.save({id:i, address: "address" + i});
}

findで確認します。

> db.users.find()
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf271"), "id" : 0, "address" : "address0" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf272"), "id" : 1, "address" : "address1" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf273"), "id" : 2, "address" : "address2" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf274"), "id" : 3, "address" : "address3" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf275"), "id" : 4, "address" : "address4" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf276"), "id" : 5, "address" : "address5" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf277"), "id" : 6, "address" : "address6" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf278"), "id" : 7, "address" : "address7" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf279"), "id" : 8, "address" : "address8" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf27a"), "id" : 9, "address" : "address9" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf27b"), "id" : 10, "address" : "address10" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf27c"), "id" : 11, "address" : "address11" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf27d"), "id" : 12, "address" : "address12" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf27e"), "id" : 13, "address" : "address13" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf27f"), "id" : 14, "address" : "address14" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf280"), "id" : 15, "address" : "address15" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf281"), "id" : 16, "address" : "address16" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf282"), "id" : 17, "address" : "address17" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf283"), "id" : 18, "address" : "address18" }
{ "_id" : ObjectId("590dddf0f62e1b1cfe7bf284"), "id" : 19, "address" : "address19" }

Node.jsとMongoDBの連携

今回はMongooseという、Node.jsからMongoDBを操作するためのライブラリを利用します。

まずはMongooseをインストールします。

$ npm install --save mongoose

ここからはこのMongoose経由でMongoDBにアクセスしていきます。

初めにserver直下にmodelsディレクトリを作成し、usersコレクション用のusers.model.tsを作成します。 ここに以下のようにスキーマを定義し、スキーマからモデルをコンパイルします。

users.model.ts

import * as mongoose from "mongoose";

const usersModel: mongoose.Model<mongoose.Document> = mongoose.model(
  "users",
  new mongoose.Schema({
      id : {
        type: Number
      },
      address : {
        type : String
      }
  })
);

export { usersModel };

次にMongoDBへの接続について、アプリケーションのエントリポイントであるwww.tsに追記します。

listenに成功したコールバックの中で、mongoose.connectを利用してMongoDBに接続します。 接続先はサーバのポート設定を記述したconfig.tsに外部化しておきます。

www.ts

import * as http from "http";
import { app } from "../app";
import { serverPort, mongoUri } from "../config";
import * as mongoose from "mongoose";

const port = process.env.PORT || serverPort;
app.set("port", port);

const server = http.createServer(app);

server.listen(port, () => {
  mongoose.connect(mongoUri);
});

config.ts

export const serverPort: number = 4300;
export const mongoUri: string = "mongodb://localhost/sample_db";

apiの実体であるusers.tsから実際にMongoDBへアクセスします。

先ほど作成したモデルからfindし、コレクションの全ドキュメントを取得して返します。

users.ts

import { Request, Response, Router } from "express";
import { usersModel } from "../models/users.model";

const usersRouter: Router = Router();

usersRouter.get("/", (request: Request, response: Response) => {
  usersModel.find({}, function(err, users) {
    if (err) throw err;
    response.json({users: users});
  });
});

export { usersRouter };

動作確認

これで以下のような一連の流れが完成しました。

  • Angularで構築したHTMLからExpressで構築したAPIにアクセス。
  • API側ではMongoDBのデータを取得して返答する。
  • レスポンスをAngular側で整形してテーブルを表示する。

f:id:tadajam:20170506235823p:plain

おしまい

これで全6回に渡るMEANスタック入門は完了です。 ここからさらにAngular側を掘っていくとか、Express側でRESTfulなAPIを構築していくだとか、色々とやりたいことはありますので、気が向いたらまた書きたいと思います。

最後に、記事に誤っている部分を発見した方や、もっと良い方法をご存じの方はぜひお声がけ下さい。