LoginSignup
2
5

More than 5 years have passed since last update.

MongoDB 詰まった所メモ

Last updated at Posted at 2018-01-17

概要

MongoDBのEmbedded Documentにおいて詰まった所をメモします。

MongoDBのデータの保存の仕方について。

MongoDBはNoSQLデータベースと分類されており、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する。
(Wikiより引用)
つまり従来のRDBMSと違い、テーブルにデータを保存していくのではなく、全てを連想配列のような形で保存しています。
※その他のMongoDBについての用語や仕組みはWikiを参照

作成

Node.jsでMongoDBを扱うためにmongooseというライブラリを利用します。

インストール

$ npm install mongoose

スキーマ定義

今回はToDoリスト作成し、スキーマを下記の通りに設定。

sampleSchema.js
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作成日
        • 期限

もしここでEmbedded Documentしなかった場合、データベースが第1正規形のようにただのデータの羅列になってしまい、のちにfindする際にクエリが複数必要となってしまうので注意です。

ドキュメントの追加

mongooseにはsaveというメソッドがあり、

sampleMethod.js
var Todo = mongoose.model('Todo');
var todo = new Todo();
todo.listName = 'リスト名';
todo.save();

上のsampleMethod.jsのようにmodel新規作成->saveで格納でき、更にIDの割り当ても自動でやってくれます。

では、新たにドキュメント内のドキュメントに追加するにはどうするか?

sampleAddTodo.js
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を変える場合

sampleUpdate.js
Todo.findOneAndUpdate({query}
      $set: {
        'details.$.tf': true/false
      },
      function (err, todos) {
          // ...
});

[$]にたどり着くまでが一番時間がかかりました。参照1 参照2

そして、ToDo・ToDoリストを検索する場合

sampleUpdateTodo.js
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

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5