Edited at

Node.jsからMongoDBに接続してみる

More than 1 year has passed since last update.

CentOS7にMongoDBをインストール〜MongoDB起動〜mongoShell起動」に引き続き、Node.jsからMongoDBに接続してみたいと思います。CentOS7がVagrant+VirtualBox上で立ち上がっていて、MongoDBは3.4.10、Node.jsは9.2.0です。

MongoDB NodeJS Driverを見ながらやっていきます。


nodeプロジェクトの準備

/vagrantディレクトリがsynced folderになっているので、その中にmongolessonディレクトリを作ってやっていきます。処理を書いていくapp.jsファイルも同時に作っておきます。

$ cd /vagrant

$ mkdir mongolesson
$ cd mongolesson
$ npm init -y
$ touch app.js
$ ls
app.js package.json

準備できました。


MongoDB NodeJS Driverの導入

とりあえず必要なのはmongodbのドライバーだけなのですが、ESLintも入れておきます

$ npm install mongodb esLint


MongoDBに接続する前に

MongoDBサーバーが起動していて、データベースディレクトリが作成されていることが必要です。mongoコマンドでシェルが起動すればOKなはずです。

$ mongo

MongoDB shell version v3.4.10
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.10
...

このときに出てきたmongodb://127.0.0.1:27017をメモしておきます。


MongoDBに接続する

MongoDBに接続するjsファイルを書きます。ほぼドキュメント通りです。

MongoClient.connect(url, [option], [callback])の第1引数に渡すURLですが、mongoシェルを起動したときにメモしたものにデータベースの名前をつなげたものです。データベース自体は作成していなくても問題ありません。また、初期設定だと127.0.0.1がlocalhostに割り当てられていると思うので、URLをmongodb://localhost:27017/myDBとしてもOKです。

assertモジュールは通常ユニットテストを書くときに使うものですが、errが発生していないことの確認に使っています。


app.js

const mongodb = require('mongodb')

const MongoClient = mongodb.MongoClient
const assert = require('assert')

MongoClient.connect('mongodb://127.0.0.1:27017/myDB', (err, db) => {
assert.equal(null, err)
console.log("Connected successfully to server")
db.close()
})


実行してみます。

$ node app.js

Connected successfully to server

このようになれば成功です。


insertしてみる

app.jsにinsertを行う関数を追加します。


app.js

const mongodb = require('mongodb')

const MongoClient = mongodb.MongoClient
const assert = require('assert')

MongoClient.connect('mongodb://localhost:27017/myDB', (err, db) => {
assert.equal(null, err)
console.log("Connected successfully to server")
insertDocuments(db, () => {
db.close()
})
})

const insertDocuments = (db, callback) => {
const documents = [
{ a: 1 },
{ a: 2 },
{ a: 3 }
]
// myDBデータベースのdocumentsコレクションに対して
// ドキュメントを3つ追加します
db.collection('documents').insertMany(documents, (err, result) => {
// insert結果の確認
assert.equal(err, null)
assert.equal(3, result.result.n)
assert.equal(3, result.ops.length)

console.log("Inserted 3 documents into the collection")
callback(result)
})
}


実行してみます。

$ node app.js

Connected successfully to server
Inserted 3 documents into the collection

成功したようなのでmongoシェルでも確認してみます。

$ mongo

...

> use myDB
switched to db myDB
> show collections
documents
> db.documents.find()
{ "_id" : ObjectId("5a13aa733c67677b0a26437b"), "a" : 1 }
{ "_id" : ObjectId("5a13aa733c67677b0a26437c"), "a" : 2 }
{ "_id" : ObjectId("5a13aa733c67677b0a26437d"), "a" : 3 }

myDBデータベースは作成していませんが、自動で作成されています。また、documentsコレクションも作成され、3つのドキュメントが追加されています。


ES6でのMongoDBへの接続

Quick StartではこのMongoClient.connect()の中でMongoDBに接続し、insertなどの処理を呼び出しています。これはこれで良いのですが、MongoClient.connect()がPromiseを返すことを利用することもできます。MongoClient

ドキュメントでは以下のようなcoを利用したコードになっています。


app_es6.js

const mongodb = require('mongodb')

const MongoClient = mongodb.MongoClient
const co = require('co')
const assert = require('assert')

co(function* () {
const db = yield MongoClient.connect('mongodb://localhost:27017/myDB')
console.log("Connected successfully to server")
db.close()
}).catch(err => {
console.log(err.stack);
})


実行してみると

$ node app.js

Connected successfully to server

いけます。nodeのバージョンが古いとエラーが出るということもあるかもしれません。これでもいけるのですが、coの使い方というかGeneratorがよくわかっていないので、普通にthenやcatchでつなげた書き方にしてみたいと思います。


app_es6.js

const mongodb = require('mongodb')

const MongoClient = mongodb.MongoClient

MongoClient.connect('mongodb://localhost:27017/myDB').then(db => {
console.log("Connected successfully to server")
db.close()
}).catch(err => {
console.log(err)
})


$ node app.js

Connected successfully to server

いけます。insertもやってみます。

const mongodb = require('mongodb')

const MongoClient = mongodb.MongoClient
const assert = require('assert')

MongoClient.connect('mongodb://localhost:27017/myDB').then(db => {
db.collection('documents').insertMany([
{ b: 1 },
{ b: 2 },
{ b: 3 }
], (err, result) => {
assert.equal(err, null)
assert.equal(3, result.result.n)
assert.equal(3, result.ops.length)
console.log("Inserted 3 documents into the collection")
})
db.close()
}).catch(err => {
console.log(err)
})

$ node app_es6.js 

Inserted 3 documents into the collection
$ mongo
...

> use myDB
> db.documents.find()
{ "_id" : ObjectId("5a13aa733c67677b0a26437b"), "a" : 1 }
{ "_id" : ObjectId("5a13aa733c67677b0a26437c"), "a" : 2 }
{ "_id" : ObjectId("5a13aa733c67677b0a26437d"), "a" : 3 }
{ "_id" : ObjectId("5a13b378f8ce107b7021881e"), "b" : 1 }
{ "_id" : ObjectId("5a13b378f8ce107b7021881f"), "b" : 2 }
{ "_id" : ObjectId("5a13b378f8ce107b70218820"), "b" : 3 }

入りました。Promiseを使った書き方もできますね。次は実際にアプリケーションに組込んでみたいと思います。