#概要
MongoDBのEmbedded Documentにおいて詰まった所をメモします。
###MongoDBのデータの保存の仕方について。
MongoDBはNoSQLデータベースと分類されており、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する。
(Wikiより引用)
つまり従来のRDBMSと違い、テーブルにデータを保存していくのではなく、全てを連想配列のような形で保存しています。
※その他のMongoDBについての用語や仕組みはWikiを参照
#作成
Node.jsでMongoDBを扱うためにmongooseというライブラリを利用します。
インストール
$ npm install mongoose
##スキーマ定義
今回はToDoリスト作成し、スキーマを下記の通りに設定。
var Schema = mongoose.Schema;
var todoSchema = new Schema({
tf: {
type: Boolean,
default: false
},
content: String,
createdDate: {
type: Date,
default: Date.now
},
limitDate: Date
});
var todoList = new Schema({
listName: String,
createdDate: {
type: Date,
default: Date.now
},
details: [todoSchema]
});
mongoose.model('Todo', todoList);
MongoDB にはドキュメントの中にドキュメントを埋め込む Embedded Document という概念があります。
上のsampleSchema.jsを例に説明すると、
todoListというスキーマを定義する際に、todoSchemaをdetailsというフィールドの値として保存しています。
こうすることでToDoリストのデータ構造は下の状態になります。
- ToDoリスト
- ToDoリスト名
- ToDoリスト作成日
- 詳細
- ToDo1
- チェック
- 内容
- ToDo作成日
- 期限
- ToDo2
- チェック
- 内容
- ToDo作成日
- 期限
- ToDo1
もしここでEmbedded Documentしなかった場合、データベースが第1正規形のようにただのデータの羅列になってしまい、のちにfindする際にクエリが複数必要となってしまうので注意です。
##ドキュメントの追加
mongooseにはsaveというメソッドがあり、
var Todo = mongoose.model('Todo');
var todo = new Todo();
todo.listName = 'リスト名';
todo.save();
上のsampleMethod.jsのようにmodel新規作成->saveで格納でき、更にIDの割り当ても自動でやってくれます。
では、新たにドキュメント内のドキュメントに追加するにはどうするか?
var Todo = mongoose.model('Todo');
Todo.findOne({query},
function (err, todos) {
var todo = {};
todo.tf = false;
todo.content = '内容';
todo.limitDate = limit;
todo.createdDate = Date.now();
todos.details.push(todo);
todos.save(function (err) {
// ...
});
});
コレクションを検索
↓
配列作成
↓
作成した配列をドキュメントに追加
この方法で追加できます。このやりかたでもIDの割り当てが自動でされるのでとても便利です。
##検索
正直、検索が一番躓きました。
まずは、クライアントのチェックに応じてtrue/falseを変える場合
Todo.findOneAndUpdate({query}
$set: {
'details.$.tf': true/false
},
function (err, todos) {
// ...
});
[$]にたどり着くまでが一番時間がかかりました。参照1 参照2
そして、ToDo・ToDoリストを検索する場合
Todo.find({
$or: [{
listName: new RegExp('.*' + '検索名' + '.*', 'i')
},
{
'details.content': new RegExp('.*' + '検索名' + '.*', 'i')
}
]
}, function (err, todos) {
// ...
});
MongoDBの特徴として、検索の際に正規表現検索が使えるのでRegExpを使います。文字列(検索名)を全文検索することができます。
こちらは、[$]は用いません。難しい。
#おわりに
後半適当になってしまい申し訳ありません。NoSQLではMongoDBはライブラリも充実してますし導入にはいいなと思いました。興味ある方は初めてみることをお勧めします。最後までご覧頂きありがとうございました。
##参考サイト
node.js から MongoDB にアクセス (Mongoose の紹介) - KrdLab's blog