文書の過去の版を表示しています。
目次
MongoDB
MongoDBは、NoSQLの分散データベース
リレーショナルDBとの差異
MySQL | MongoDB | |
---|---|---|
種類 | リレーショナルDB | ドキュメント指向DB |
データ要素の集合 | テーブル | コレクション |
データ構造 | タプル(=行) | ドキュメント |
属性 | カラム | フィールド |
CAP定理 | 一貫性・可用性を保証 | 可用性・分断耐性を保証 |
トランザクション | あり | なし |
MongoDBのドキュメントはBSON(Binary JSON)形式で保存される。JSONで定義されているデータ(オブジェクト・配列・文字列・数値・真偽値・null)と日付(ISODate)を保存できる。トランザクションは存在しないがドキュメント単位でアトミックな操作が保証されている。
インストール
MacOSX
$ sudo port install mongodb
startup itemに追加
$ sudo port load mongodb
起動
自身の権限で起動してみる
$ mongod --dbpath=/Users/nullpon/data
dbpathはデータ保存場所、自身の権限で起動するので自分のホームディレクトリ以下のなど書き込み可能な適当な場所を指定する。dbpathのデフォルトは /data/db 。保存場所が存在しない場合や、読み書き権限が無い場合は起動に失敗するので予め作成しておく。デフォルトでPort 27017を使用する。
インタラクティブシェル
mongoコマンドでインタラクティブシェルを起動する。
$ mongo
testという名前のDBに接続する。指定したdbが存在しなくても良い
$ mongo test
hostとDBを指定して起動
$ mongo localhost/test
host、port、DBを指定して起動
$ mongo localhost:27017/test
host、port、DBのデフォルトは localhost 27017 test である
mongoシェルではJavaScriptの文法でDBを操作する
> db.hoges.save({ fuga: 1, piyo: 2 }) > db.hoges.save({ fuga: 1, piyo: 3 }) > db.hoges.find() { "_id" : ObjectId("4ef94f405a360248562915f4"), "fuga" : 1, "piyo" : 2 } { "_id" : ObjectId("4ef94f6b5a360248562915f5"), "fuga" : 1, "piyo" : 3 }
※ save時にコレクションが存在しなくても良い
mongoシェルプロンプトを起動せずに実行
$ mongo dbname --quiet --eval="db.collectionName.count();" $ mongo localhost:27017/test < hogehoge.js
evalの場合、 show collections 等を実行できない
DB管理
DB削除
use DatabaseName; db.dropDatabase();
クエリ
mongoインタラクティブシェルで使えるクエリ
※ 以下Collectionには任意のコレクション名が入る
検索
db.Collection.find();
完全一致検索
db.Collection.find({name: "hogefuga"});
正規表現(前方一致)検索
db.Collection.find({name: /^hoge/});
ソート(1: asc, -1: desc)
db.Collection.find().sort({ name: 1 })
変数に結果を格納して利用できる
var a = db.CollectionA.findOne({_id: "hoge"}); db.CollectionB.find({ a_code: a.code });
管理画面
ブラウザでアクセスできるコンソールページ、mongodのport+1000のポートを使う。デフォルトは28017となる。
<html>–rest</html>オプションを付けて起動すると、RESTでDBを操作可能になる
Sharding
FAQ
can't do non-multi update with query that doesn't have a valid shard key
updateしようとすると、 can't do non-multi update with query that doesn't have a valid shard key
と出る
条件
- nodeのnativeドライバ
- コレクションがシャーディングされている
解決法
- updateのmultiフラグをtrueにする。
valid shard key must be in update object for collection
updateクエリで、 valid shard key must be in update object for collection:
というエラーが出る
条件
- nodeのnativeドライバ
- コレクションがシャーディングされている
解決法
- update object に _id を加える
- または、upsertで実行する
コネクション数上限を増やしたい
オープン可能なファイルディスクリプタ数の80%がコネクション数の上限。ulimit -n
でオープン可能なファイル数を増やす。
※ コネクション数の上限は、mongodに接続して db.serverStatus()
で表示されるconnectionsのcurrentとavailableの合計値
can't upsert something without full valid shard key
upsertクエリで、 can't upsert something without full valid shard key:
というエラーが出る
シャーディング環境では $in による複数 id 指定などでの upsert を受け付けないので、あらかじめ指定する id のドキュメントを作っておき、update で実行する。
full shard key must be in update object for collection
シャーディング環境のupdateクエリで発生、updateで$setを使わないオブジェクト全体の更新をするとエラーになる。
db.Collection.update({_id: "hoge"}, {value: 100});
これは更新されるオブジェクトに_idが入っていないため、
db.Collection.update({_id: "hoge"}, {_id: "hoge", value: 100});
とすればエラーにならないが、ドキュメント全体更新は危険なので $setや$unsetを使うことをお勧めする。