Compose MongoDB の Node.js アプリ開発の事始め 


Bluemix からも利用できる IBM Compose の提供サービスの一つ MongoDB を Node.js からアクセスするコーディングについて試したメモです。 本メモでは、MongoDB の APIライブラリとして [mongoose](http://mongoosejs.com/) を利用します。


![スクリーンショット 2017-06-30 16.36.23.png](https://qiita-image-store.s3.amazonaws.com/0/42829/b0176d79-6d67-1f87-4dac-22eeb0cc42a9.png "スクリーンショット 2017-06-30 16.36.23.png")

# 基礎知識

## Compose について
Qiita に投稿した [Bluemix で使えるComposeとはなんですか？ について調べてみた](http://qiita.com/MahoTakara/items/a614df96059d3d8749a1) の参照してくださいね。

## MongoDB について
MongoDBは、オープンソースソフトウェアのドキュメント指向データベースである。C++言語で記述されており、開発とサポートはMongoDB Inc.によって行なわれている。 
MongoDBはRDBMSではなく、いわゆるNoSQLと呼ばれるデータベースに分類されるものである。RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する（このデータの物理的な格納はBSONと呼ばれるJSONのバイナリ版といえる形式で行われる）。コレクションはRDBMSのような固定的なスキーマを持たない。ドキュメントには複雑な階層構造を持たせることもでき、それらの構造に含まれるフィールドを指定したクエリやインデクス生成も簡単な指定によって行える。RDBMSのように高度な結合操作を効率的に行うことはできないが、データの追加・更新・削除・クエリは高速に行うことができる。また、アプリケーションは自身の構造やデータ型に合った自然な形でデータを格納することができるため、扱うデータの特性によっては、RDBMSよりも容易かつ迅速に開発を行える可能性がある。 参考資料(4)

## mongoose について
Mongooseは、アプリケーションのデータをモデル化するための、ストレート・フォワードなスキーマベースの対策を提供します。 これには、組み込みの型キャスト、検証、クエリ構築、ビジネスロジックフックなどが含まれています。 参考資料(1) 
MongoDBの様なKVS型データベースは、構造的に容易にスケールできる事や、クラスタリングしたサーバー構成によって、性能をリニアに向上できる点、そして、大容量のデータを扱えるなどの特徴があります。しかし、アプリケーションを開発する場合、RDBの様にデータの構造をプログラミング上で一貫性を持って開発することには、難点があります。 そこで、mongoose のソリューションが必要となる訳です。

# Compose MongoDB への接続

mongoose のチュートリアルでは、MongoDBへ接続するサンプルコードとして、次の様（参考資料1)なシンプルなコードが提示されていますが、

~~~
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
~~~

クラウドのマルチテナント環境のデータベースサービスで、上記の様な接続では、安心安全を確保できません。 そこで、厳重な認証と暗号化通信の手段が提供されており、このルールに従ったアクセスが必要になります。 この方法は、[【Qiita】Compose MongoDB へ node.js からアクセスする](http://qiita.com/MahoTakara/items/842a6d3690015e720ff7) に書いておきましたので、参照してください。

# Mongoose コード パターン

## スキーマとモデル
スキーマからモデルを作成します。

~~~
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// スキーマの作成
var userSchema = new Schema({
    name: String,
    username: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    admin: Boolean,
    location: String,
    meta: {
       age: Number,
       website: String
    },
    created_at: Date,
    updated_at: Date
});

// モデルの作成
var User = mongoose.model('User', userSchema);
~~~
monngoose doc: [Schemas](http://mongoosejs.com/docs/guide.html)
monngoose doc: [Model](http://mongoosejs.com/docs/models.html)



## データの登録
モデルに、データを与えてインスタンスを作成します。

~~~
//モデルの作成
var User = require('./models/user');

// ユーザデータ                                                                                                            
var userData = {
    name: 'ごま',
    username: 'gomagoma',
    password: 'hogehoge'
};

// インスタンス作成
var user = new User(userData);

// データベースへ書き込み
user.save(function(err) {
  　if (err) throw err;
    console.log('データ登録成功');
});
~~~
monngoose doc: [Model#save](http://mongoosejs.com/docs/api.html#model_Model-save)



## FIND取出し
findの第一引数に条件を設定できます。 

~~~
var User = require('./models/user');

// 全データの読み込み                                                                                                      
User.find({}, function(err, users) {
    if (err) throw err;
    console.log(users);
});
~~~
ユーザー名に一致する条件で検索の例です。

~~~
var User = require('./models/user');

// ユーザー名に一致する条件で検索
User.find({ username: 'gomagoma' }, function(err, user) {
    if (err) throw err;
    console.log(user);
});
~~~
その他にも、大小比較条件などの例が以下のリンクにあります。
monngoose doc: [Model#save](http://mongoosejs.com/docs/api.html#model_Model.find)


## 更新
queryの条件に一致するデータをnew_docで置き換えます。

~~~
var query = { username: 'gomagoma' }
var new_doc = { username: 'gomagoma', password: 'damedame' }
User.update(query, new_doc, function(err) {
    if (err) throw err;
    console.log('更新完了');
    callback(null);
});
~~~
monngoose doc: [Model#update](http://mongoosejs.com/docs/api.html#model_Model.update)



## 削除

~~~
var User = require('./models/user');

// 削除                                                                                                                    
User.remove({ username: 'gomagoma' }, function(err, user) {
	if (err) throw err;
	console.log('削除成功');
});
~~~
monngoose doc: [Model#remove](http://mongoosejs.com/docs/api.html#model_Model.remove)



# サンプルコード

サンプルコードの実行できる形式のファイルは、次のGitHubにあります。
https://github.com/takara9/mongodb_mongoose





# 参考資料
(1) Elegant MongoDB object modeling for Node.js http://mongoosejs.com/
(2) Bluemix で使えるComposeとはなんですか？ について調べてみた http://qiita.com/MahoTakara/items/a614df96059d3d8749a1
(3) mongoDB Home page https://www.mongodb.com/
(4) ウィキペディア MongoDB https://ja.wikipedia.org/wiki/MongoDB
(5) mongoose doc http://mongoosejs.com/docs/guide.html