カテゴリー別アーカイブ: MongoDB

Node.js + MongoDBでサウンドパッチシステム

Node.js + MongoDBでユーザ登録システムを作成したのをベースに, サウンドのセッティングをMongoDBに保存・ロードするところまで完成した. あとは, パッチの更新と削除処理と, セッション管理を実装すればとりあえず構想していたのは完成する.

ただ, セッション管理が結構問題で, Node.jsでは, PHPの$_SESSIONスーパーグローバル変数のように, セッション管理機能をもたない (らしい…). Node.jsでセッション管理するための正攻法としては, 最もメジャーなNode.jsのフレームワークであるexpressを使うこと.

…なんだけど, Node.js (+ MongoDB)を利用した (それなりに本格的な) Webアプリケーションの作成は初めてなので, フレームワークは使わないという方針で作ってきた.

となると, 自分でセッション管理を実装するか, 妥協してexpressを使うか…

 

Node.js + MongoDB クエリオブジェクト

Node.js + MongoDBでのドキュメントの検索や更新の際には, 対象のドキュメントを指定するためにクエリオブジェクトを定義してメソッドに渡す必要があります.

例えば, usernameというキーが’rilakkuma’のドキュメントのみを取得する場合,

// monogdbの読み込み
var mongodb  = require('mongodb');

// mongodb.Serverインスタンスの生成
// ポート番号はデフォルトでは27017です.
// 利用していないポート番号であれば変更可能です.
var server   = new mongodb.Server(host, mongodb.Connection.DEFAULT_PORT);

// データベースの作成 (mongodb.Dbインスタンスの生成)
// 第1引数のデータベース名は適宜変更してください
// 第2引数にはmongodb.Serverインスタンスを指定します.
// 第3引数はオプションですが, safeモードは有効にしておいたほうがいいでしょう.
var database = new mongodb.Db('database_name', server, {safe : true});

// データベースのオープン (コネクションの確立)
// 非同期APIなので, コールバック関数を指定して, オープンされたmongodb.Dbインスタンスを参照する.
// コールバック関数の第1引数は, Node.jsの非同期APIと同様にエラーオブジェクトが渡されます.
database.open(function(error, database) {
    if (error) {
        console.error(error);
        return;
    }

    // mongodb.Dbインスタンスのcollectionメソッドに
    // コレクション名を指定して,
    // mongodb.Collectionインスタンスを生成します.
    // このインスタンスからCRUDのためのメソッドを呼び出します.
    var collection = database.collection('samples');

    var query = {username : 'rilakkuma'};

    var cursor = collection.find(query);
});

また, クエリオブジェクトには, 単なる値の指定だけでなく, 表に記載しているようなキーワードを利用することで, より柔軟なクエリ力を発揮することができます.

Keyword Condition
$gt 指定した値より大きい
$lt 指定した値より小さい
$gte 指定した値以上
$lte 指定した値以下
$ne 指定した値でない
$exists trueであれば, キーが存在するドキュメント. falseであればキー存在しないドキュメント
$or クエリオブジェクトを論理和で連結
$nor クエリオブジェクトを否定論理和で連結
$and クエリオブジェクトを論理積で連結

…etc

例えば, usernameというキーが存在し, かつ, ageキーの値が20以上のドキュメントを取得するクエリオブジェクトは, こんな感じになります.

var query = {
    $and : [
        {username : {$exists : true}},
        {age           : {$gte      : 20  }}
    ]
};

MongoDB アトミックなAPI

MongoDBにはRDBのような, トランザクションがありません.
そこで, 検索と更新 / 検索と削除をアトミックに処理するためのAPIが定義されています.
まずは, コレクションの取得までのおさらい.

// monogdbの読み込み
var mongodb  = require('mongodb');

// mongodb.Serverインスタンスの生成
// ポート番号はデフォルトでは27017です.
// 利用していないポート番号であれば変更可能です.
var server   = new mongodb.Server(host, mongodb.Connection.DEFAULT_PORT);

// データベースの作成 (mongodb.Dbインスタンスの生成)
// 第1引数のデータベース名は適宜変更してください
// 第2引数にはmongodb.Serverインスタンスを指定します.
// 第3引数はオプションですが, safeモードは有効にしておいたほうがいいでしょう.
var database = new mongodb.Db('database_name', server, {safe : true});

// データベースのオープン (コネクションの確立)
// 非同期APIなので, コールバック関数を指定して, オープンされたmongodb.Dbインスタンスを参照する.
// コールバック関数の第1引数は, Node.jsの非同期APIと同様にエラーオブジェクトが渡されます.
database.open(function(error, database) {
    if (error) {
        console.error(error);
        return;
    }

    // mongodb.Dbインスタンスのcollectionメソッドに
    // コレクション名を指定して,
    // mongodb.Collectionインスタンスを生成します.
    // このインスタンスからCRUDのためのメソッドを呼び出します.
    var collection = database.collection('samples');
});

 

API Description
collection.findAndModify(query, sort, document, options, function(error, result) {}) データの取得と更新を同時に実行する. 第1引数はMongoDBが定義するクエリオブジェクト, 第3引数が更新後のドキュメント. コールバック関数には, エラーオブジェクトと取得したドキュメントが渡される.
collection.findAndRemove(query, sort, options, function(error, result){}) データの取得と削除を同時に実行する. 第1引数はMongoDBが定義するクエリオブジェクトでこれに該当するドキュメントが削除される. コールバック関数には, エラーオブジェクトと取得したドキュメントが渡される.

Node.js + MongoDB CRUD API

Node.js + MongoDBのCRUD APIをまとめてみました.

と, その前に, MongoDBでCRUD APIを利用するためには, その起点となるコレクションが必要です (コレクションとはRDBでのテーブルに相当します).

// monogdbの読み込み
var mongodb  = require('mongodb');

// mongodb.Serverインスタンスの生成
// ポート番号はデフォルトでは27017です.
// 利用していないポート番号であれば変更可能です.
var server   = new mongodb.Server(host, mongodb.Connection.DEFAULT_PORT);

// データベースの作成 (mongodb.Dbインスタンスの生成)
// 第1引数のデータベース名は適宜変更してください
// 第2引数にはmongodb.Serverインスタンスを指定します.
// 第3引数はオプションですが, safeモードは有効にしておいたほうがいいでしょう.
var database = new mongodb.Db('database_name', server, {safe : true});

// データベースのオープン (コネクションの確立)
// 非同期APIなので, コールバック関数を指定して, オープンされたmongodb.Dbインスタンスを参照する.
// コールバック関数の第1引数は, Node.jsの非同期APIと同様にエラーオブジェクトが渡されます.
database.open(function(error, database) {
    if (error) {
        console.error(error);
        return;
    }

    // mongodb.Dbインスタンスのcollectionメソッドに
    // コレクション名を指定して,
    // mongodb.Collectionインスタンスを生成します.
    // このインスタンスからCRUDのためのメソッドを呼び出します.
    var collection = database.collection('samples');
});
CRUD API Description
Create collection.insert(docs, options, function(error, result) {}) 第1引数には, 保存するJavaScriptのプレインオブジェクトを指定します. また, これはドキュメントと呼ばれ, RDBでのレコードに相当します. コールバック関数には, エラーオブジェクトと追加したドキュメント (プレインオブジェクト) が渡されます.
Read var cursor = collection.find(query, fields, options);cursor.toArray(function(error, docs) {}); /* or */cursor..each(function(error, docs) {}); findメソッドの第1引数には, MongoDBが定義するクエリオブジェクトを指定します.
findメソッドの戻り値として, mongodb.Cursorインスタンスを取得できるので,
そのインスタンスのtoArrayメソッド (ドキュメントをまとめて取得), または, eachメソッドを (1ドキュメントずつ取得) 呼び出します. コールバック関数には, エラーオブジェクトと, toArrayメソッドであればドキュメントの配列, eachメソッドであればドキュメントが渡されます.
Update collection.update(selector, docs, options, function(error, numberOfUpdatedDocs) {}) 第1引数には, MongoDBが定義するクエリオブジェクトで更新対象となるドキュメントを指定します. 第2引数は更新後のドキュメントです. コールバック関数にはエラーオブジェクトと更新されたドキュメントの数が渡されます.
Delete collection.remove(selector, options, function(error, numberOfRemovedDocs) {}) 第1引数には, MongoDBが定義するクエリオブジェクトで削除対象となるドキュメントを指定します.
コールバック関数にはエラーオブジェクトと削除されたドキュメントの数が渡されます.

Node.js + MongoDB

今日は, Node.jsからMongoDBを扱うための最初の処理についてまとめておきます.

とその前に, MongoDBの概要について簡単に解説しておきます. MongoDBはMySQLなどのRDBではなく, NoSQLのデータベースです. つまり, MongoDBには, SQLの概念はなく, CRUDのためにはそれぞれに相当するメソッドを利用します. したがって, DBに対するクエリ力ではRDBに劣ってしまいますが, スキーマレスという特徴をもっており, RGBのようにテーブル定義が必要ない (ただし, テーブルに相当する概念である, コレクションはあります) ので, 分散処理などに向いています.

非同期なAPIを定義しており, また, 連想配列を永続化するDBなので, Node.jsとの相性はバツグンです.

さて, 前置きはこれぐらいにしていNode.jsからMongoDBを扱うまでのコードをまとめます.

// monogdbの読み込み
var mongodb  = require('mongodb');

// mongodb.Serverインスタンスの生成
// ポート番号はデフォルトでは27017です.
// 利用していないポート番号であれば変更可能です.
var server   = new mongodb.Server(host, mongodb.Connection.DEFAULT_PORT);

// データベースの作成 (mongodb.Dbインスタンスの生成)
// 第1引数のデータベース名は適宜変更してください
// 第2引数にはmongodb.Serverインスタンスを指定します.
// 第3引数はオプションですが, safeモードは有効にしておいたほうがいいでしょう.
var database = new mongodb.Db('database_name', server, {safe : true});

// データベースのオープン (コネクション確立)
// 非同期APIなので, コールバック関数を指定して, オープンされたmongodb.Dbインスタンスを参照する.
// コールバック関数の第1引数は, Node.jsの非同期APIと同様にエラーオブジェクトが渡されます.
database.open(function(error, database) {
    if (error) {
        console.error(error);
        return;
    }

    console.log('Open >> ');
    console.dir(database);
});

MongoDBのインストール (Mac OS X)

Mac OS XにMongoDBをインストールしたので, その手順を備忘録的に…

1. MongoDBのインストール

sudo npm install -g mongodb

2. インストールの確認

$ ls -l  /usr/local/lib/node_modules
total 0
drwxr-xr-x  10 nobody  staff  340 12 28 03:34 connect-memcached
drwxr-xr-x  10 nobody  staff  340  1 15 20:59 connect-mongo
drwxr-xr-x  13 nobody  staff  442 12 28 03:33 connect-redis
drwxr-xr-x  12 nobody  staff  408 12 28 03:33 connect-redis-sessions
drwxr-xr-x  10 nobody  staff  340  1 16 01:34 express
drwxr-xr-x   8 nobody  staff  272  1 15 23:06 express-generator
drwxr-xr-x   9 nobody  staff  306  1 12 21:17 express-session
drwxr-xr-x   9 nobody  staff  306  1 15 21:02 formidable
drwxr-xr-x  15 nobody  staff  510 12 28 03:33 jade
drwxr-xr-x  15 nobody  staff  510 12 28 03:33 memcached
drwxr-xr-x  12 nobody  staff  408  1 16 00:27 mongodb
drwxr-xr-x  11 nobody  staff  374 12 28 03:33 mysql
drwxr-xr-x   7 nobody  staff  238  1 12 21:17 n
drwxr-xr-x  11 nobody  staff  374  1 15 21:02 nodemailer
drwxr-xr-x  25 nobody  staff  850  1 12 21:17 npm
drwxr-xr-x   7 nobody  staff  238 12 28 03:33 readline
drwxr-xr-x  17 nobody  staff  578 12 28 03:33 websocket
drwxr-xr-x  12 nobody  staff  408  4  5  2014 websocket-server
drwxr-xr-x  17 nobody  staff  578  1 15 21:03 ws

/usr/local/lib/node_modules ディレクトリ以下にmongodbが表示されていればOKです.

もっとも, これだけでは, MongoDBを操作することができないので, mongoシェルとmongod (MongoDBのデーモン) をインストールします.

* Homebrew or MacPortsのインストール

mongoシェルとmongod (MongoDBのデーモン) のインストールには, HomebrewかMacPortsコマンドのインストールが必要です. もっとも, Homebrew or MacPortsはMac OS Xで開発をするならインストールしておくべきですね.

もし, すでにインストールされている場合は, 念のためアップデートしておきましょう.

$ brew update

or,

$ sudo port selfupdate

3. mongoシェルとmongod (MongoDBのデーモン)のインストール

$ brew install mongodb

or,

$ sudo port install mongodb

4. インストールの確認

mongoシェル

$ which mongo
/opt/local/bin/mongo

mongod (MongoDBのデーモン)

$ which mongod
/opt/local/bin/mongod

以上のようにコマンドのパスが表示されていればOKです.

これで完了です.