使用するソフトウェア
Node.js v8.9.1
Express 4.16.0
MongoDB v4.0.5
mongoose 5.4.7
body-parser 1.18.3
前提
Node.jsとexpressで簡単なWebAPIを提供するところまでできていること。
Node.jsとexpressを使って簡単なWebAPIを作成する
Node.jsとexpressの準備
以下の記事を参考に、Node.jsとexpressでWebAPIを作成できる状態にしておく。
Node.jsとexpressを使って簡単なWebAPIを作成する
MongoDBの準備
MongoDBのインストーラをダウンロード
MongoDBはクラウド版とサーバ版があるが、今回はローカルでDBを使用したいのでサーバ版をダウンロードする。
MongoDB community版ダウンロード
MongoDBのインストール
インストーラを実行して、ウィザードに沿ってそのままインストールすればよい。
途中でMongoDBのサービスをインストールするか聞かれるので、デフォルトのままネットワークサービスユーザで実行する設定にしている。
MongoDBのPathを通す
システム環境変数の設定
Windowsのシステム環境変数Pathに以下のパスを追加する。
MongoDBのPathが通ったか確認する
Windowsを再起動し、コマンドプロンプトで以下のコマンドを実行する。
mongo --verion
MongoDBのバージョンが表示されたらPathが通っている。
MongoDBの設定
必要に応じてMongoDBの設定を変更する。
設定はMongoDBのインストールディレクトリ\bin\mongod.cfg
で行う。
データベースの格納場所を変更したい場合はstorage.dbPath
、ログファイルの出力先を変更したい場合はsystemLog.path
を変更する。
デフォルトではstorage.dbPath
、systemLog.path
ともにWindowsのProglem Filesの配下を指しているが、ここだと書き込み禁止になっているためにMongoDBの起動に失敗する。
そのためC直下などにdataフォルダとlogフォルダを作成し、mongod.cfgではそれらのフォルダを使用するように書き換える。
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: C:\mongo\data
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: C:\mongo\log\mongod.log
# network interfaces
net:
port: 27017
bindIp: 127.0.0.1
#processManagement:
#security:
#operationProfiling:
#replication:
#sharding:
## Enterprise-Only Options:
#auditLog:
#snmp:
MongoDBの開始と終了
Windowsのサービスから「MongoDB」を表示し、「開始」ボタンを押すことでMongoDBがサービスとして起動する。
MongoDBを終了するときは同様に、「停止」ボタンを押すことでMongoDBのサービスが停止する。
デフォルトではスタートアップの種類は「自動」になっているので、Windows起動と同時にMongoDBのサービスが開始される。
コマンドプロンプトでMongoDBに接続
以下のコマンドを入力することで、MongoDBに接続して、対話形式でMongoDBを操作できる。
mongo
MongoDBの基本的な操作
MongoDBのデータ構造
MongoDBのデータ構造はざっくり以下のような形になっている。
一般的なRDBMSのテーブルとレコードに対して、MongoDBはコレクションとドキュメントという呼び方でデータを保持している。
RDBMS | MongoDB |
---|---|
データベース | データベース |
テーブル | コレクション |
レコード | ドキュメント |
データベースの一覧を見る
コマンドプロンプトでコマンドmongo
を入力してMongoDBに接続し、MongoDBとの対話モードでshow dbs
というコマンドを入力する。
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
デフォルトではadmin,config,localという三種類のデータベースがあらかじめ作成されている。
使用するデータベースを切り替える
使用するデータベースを切り替えるときは、use [使用するデータベース名]
というコマンドを入力する。
> use local
switched to db local
コレクションの一覧を見る
データベースの配下にあるコレクションの一覧を見たいときはshow collections
というコマンドを入力する。
> show collections
startup_log
コレクション内のドキュメントを見る
コレクションの配下にあるドキュメントを見たいときは、db.[コレクション名].find();
というコマンドを入力する。
startup_logというコレクション内にあるドキュメントを見たい場合は以下のようなコマンドとなる。
> db.startup_log.find();
データベースを作成する
新しいデータベースを作成したい場合は、use [作成するデータベース名]
というコマンドを入力する。
使用するデータベースを切り替えるときのコマンドと同じだが、データベース名が存在しない場合は自動でデータベースを作成してくれる。
> use sampledb
switched to db sampledb
コレクションを追加する
データベースにコレクションを追加するには、use [データベース名]
でデータベースを選択した状態で、db.createCollection('[コレクション名]')
というコマンドを入力する。
> db.createCollection('test_collection')
{ "ok" : 1 }
ドキュメントを追加する
コレクションにドキュメントを追加するには、use [データベース名]
でドキュメントを追加するコレクションがいるデータベースを選択した状態でdb.[コレクション名]insert();
というコマンドを入力する。
> db.test_collection.insert({name:'hogehoge', age:20});
WriteResult({ "nInserted" : 1 })
findで登録されたドキュメントの内容を見てみる。
> db.test_collection.find();
{ "_id" : ObjectId("5c4aba1d3cfc6e2de3998745"), "name" : "hogehoge", "age" : 20 }
勝手に付加されている_id
はObjectIdというもので、自動的にユニークな値が割り振られる。(RDBMSのユニークキーに相当する)
余談
MongoDBのドキュメントはRDBMSでいうところのテーブル定義のようなものは無く、JSON形式のドキュメントであれば中身のツリー構造に関係なくコレクションに登録できる。
そのため、以下のように同じコレクション内にsexがついているドキュメントと付いていないドキュメントを混在させることもできる。
> db.test_collection.insert({name:'taro', age:30, sex:'men'})
WriteResult({ "nInserted" : 1 })
> db.test_collection.find();
{ "_id" : ObjectId("5c4aba1d3cfc6e2de3998745"), "name" : "hogehoge", "age" : 20 }
{ "_id" : ObjectId("5c4abe533cfc6e2de3998746"), "name" : "taro", "age" : 30, "sex" : "men" }
Node.js+express+MongooseでMongoDBを利用する
Mongooseとは
Node.jsからMongoDBにアクセスするためのライブラリにMongooseというものがあるので、今回はこれを利用してみる。
MongooseはO/R MapperのようにMongoDBのドキュメントをオブジェクト構造で操作できるようになっている。
O/R Mapperの概要については以下のページを参照。
O/Rマッピングの役割とメリット
Mongooseのインストール
npm install mongoose --save
Mongooseについては以下のページを参考にさせていただいた。
node.js から MongoDB にアクセス (Mongoose の紹介)
MongooseでMongoDBを操作する
expressで作成したWebAPIにMongoDBへのドキュメント保存の機能を加えてみる。
expressでWebAPIを作成する手順は以下のQiitaを参照。
Node.jsとexpressを使って簡単なWebAPIを作成する
POSTリクエストのBODYに格納された情報を取り出すにはbody-parserが必要なので、以下のnpmコマンドでインストールしておく。
npm install body-parser --save
スキーマ定義
まず、MongoDBのオブジェクト構造を表すスキーマを定義する。
今回はnameとageを保持するUserというスキーマを定義している。
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const User = new Schema({
name: String,
age: Number
});
module.exports = mongoose.model('User', User);
WebAPIでMongoDBにドキュメントを保存する
WebAPIの作成
/api/v1/create-user
というWebAPIを作成し、POSTリクエストで受け取ったBODYのパラメータをMongoDBに保存する。
上記で作成したUserというスキーマ定義を利用して、インスタンスを作成してsaveを行うことでMongoDBにドキュメントが作成される。
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const User = require('./models/user');
mongoose.connect('mongodb://localhost/user');
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
// create-userの設定
app.post('/api/v1/create-user', (req, res) =>{
if (!req.body){
return res.status(500).send('reqest body empty.');
}
const instance = new User();
instance.name = req.body.name;
instance.age = req.body.age;
// MongoDBに保存
instance.save(function(err){
if(!err) {
return res.status(200).send('user create success.');
} else {
return res.status(500).send('user create faild.');
}
});
});
// イベント待機
app.listen(3000, () => console.log('Listening on port 3000'));
動作を確認
以下のコマンドでNodeサーバを起動。
node index.js
ChromeのARCなど、HTTPリクエストを送ることのできるツールを用いてWebAPIにPOSTリクエストを実行する。
MongoDBにuserというデータベースが作成され、usersというコレクションにドキュメントが追加される。
以下のコマンドでMongoDBにドキュメントが追加されたことを確認する。
> use user
switched to db user
> db.users.find();
{ "_id" : ObjectId("5c4fdadbf326d40328e4e6b8"), "name" : "taro", "age" : 20, "__v" : 0 }
WebAPIでMongoDBからドキュメントを取得する
WebAPIの作成
/api/v1/get-all-user
を追加。
findを利用してuserデータベースのusersコレクションから全ドキュメントを取得する。
取得したドキュメントをそのままレスポンスとして返す。
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const User = require('./models/user');
mongoose.connect('mongodb://localhost/user');
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
// create-userの設定
app.post('/api/v1/create-user', (req, res) =>{
if (!req.body){
return res.status(500).send('reqest body empty.');
}
const instance = new User();
instance.name = req.body.name;
instance.age = req.body.age;
// MongoDBに保存
instance.save(function(err){
if(!err) {
return res.status(200).send('user create success.');
} else {
return res.status(500).send('user create faild.');
}
});
});
// get-all-userの設定
app.get('/api/v1/get-all-user', (req, res) =>{
User.find(function(err, result){
if(!err) {
return res.json(result);
} else {
return res.status(500).send('get all user faild.');
}
});
});
// イベント待機
app.listen(3000, () => console.log('Listening on port 3000'));
動作を確認
ChromeのARCなど、HTTPリクエストを送ることのできるツールを用いてWebAPIにGETリクエストを実行する。
MongoDBからドキュメントを取得し、WebAPIのリクエストに乗せて返すことができた。