akiyoko blog

akiyoko の IT技術系ブログです

MongoDB の使い方まとめ

最近よく MongoDB を使っているのですが、ついこの間、「MongoDBの薄い本」(著:Karl Seguin・訳:濱野 司)というのを見つけて読んでみたのですが、すごく分かりやすかったのでご紹介。
コマンドを打ちながらでも1時間くらいで読み終えることができて、非常にお手軽です。


MongoDBの薄い本(The Little MongoDB Book) - cuspy diary



その前に簡単に MongoDB について説明すると、MongoDB は NoSQL のドキュメント指向データベースです(key/valueストアではありません)。
JSON によく似た BSON (JSON + datetime) 形式のデータを扱うことができ、シャーディング(複数台のサーバへのデータ水平分割による負荷分散)やレプリカセット(自動フェイルオーバによる可用性向上)といった機能がサポートされていて、さらに、スキーマレスでありながらインデックスをサポートしているという大きな特徴があります。



(私のように)長年 RDB に蝕まれてしまった脳を切り替えるには、下のような RDB用語と MongoDB用語の対応表がまずは必要だったりします(笑)。

RDB用語 MongoDB用語
データベース データベース
テーブル コレクション
ドキュメント
フィールド



 

MongoDB のインストール

Ubuntu 12.04 (on Vagrant)に MongoDB をインストールしてみます。


単に「apt-get install」しただけでは、インストールされるバージョンは「2.0.4」となり、相当古いことが判明。

$ lsb_release -d
Description:	Ubuntu 12.04 LTS

$ sudo apt-get update
$ sudo apt-get -y install mongodb
$ mongod --version
db version v2.0.4, pdfile version 4.5
Fri Aug  1 13:43:50 git version: nogitversion


そこで、公式ページ
Install MongoDB on Ubuntu — MongoDB Manual 2.6.3
を手本に、10gen のリポジトリを使ってインストールします。

# Import the public key used by the package management system
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

# Create a list file for MongoDB
$ echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list

# Reload local package database
$ sudo apt-get update

# Install the MongoDB packages
$ sudo apt-get -y install mongodb-org

$ mongod --version 
db version v2.6.3
2014-08-01T13:54:57.393+0000 git version: 255f67a66f9603c59380b2a389e386910bbb52cb

2.6.3 がインストールされました。


設定情報をチェックしておきます。

/etc/mongod.conf

dbpath=/var/lib/mongodb
logpath=/var/log/mongodb/mongod.log


 

基本系

「mongo」コマンドで、対話シェル(mongoシェル)を起動することができます。

$ mongo


mongoシェルで使える基本コマンドです。

# データベース一覧を表示
> show dbs

# データベースを選択(データベース一覧に存在していないデータベースでもOK)
> use learn

# 現在選択しているデータベースを表示
> db

# コレクション一覧を表示
> show collections

# 対話シェルを終了
> exit

 

CRUD

mongoシェルでは、JavaScript構文を使うことができます。

ドキュメント挿入

> db.unicorns.insert({name: 'Horny', dob: new Date(1992, 2, 13, 7, 47), loves: ['carrot', 'papaya'], weight: 600, gender: 'm', vampires: 63});

ドキュメント検索

# 全件表示
> db.unicorns.find()

# 1件のみ表示
> db.unicorns.findOne()

# AND条件
> db.unicorns.find({gender: 'm', weight: {$gt: 700}})

# OR条件($or 修飾子を使う)
> db.unicorns.find({gender: 'f', $or: [{loves: 'apple'}, {loves: 'orange'}, {weight: {$lt: 500}}]})

# 取得したいフィールドを限定(find() の第2引数を使う)
> db.unicorns.find(null, {name: 1});

# ソート
> db.unicorns.find().sort({name: 1, vampires: -1})

ドキュメント更新

# $set を使わないと、ドキュメント全体が書き変わってしまうので注意!
> db.unicorns.update({name: 'Roooooodles'}, {$set: {weight: 590}})

# 特殊な更新修飾子が使える
> db.unicorns.update({name: 'Pilot'}, {$inc: {vampires: -2}})

# 第3引数に true を指定すると、insert or update
> db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}}, true);

# 第4引数に true を指定すると、複数同時更新(デフォルトでは最初の1件のみ)
> db.unicorns.update({}, {$set: {vaccinated: true}}, false, true);

ドキュメント削除

> db.unicorns.remove()

その他

# コレクションの情報を表示
> db.unicorns.stats()

# 見やすいように整形
> db.unicorns.find().pretty()

# 1件スキップして2件分を表示
> db.unicorns.find().sort({weight: -1}).limit(2).skip(1)

# カウント
> db.unicorns.count({vampires: {$gt: 50}})

# インデックス作成
> db.unicorns.ensureIndex({name: 1});

# インデックス削除
> db.unicorns.dropIndex({name: 1});



ちなみに、こちらが「MongoDBの薄い本」で使うドキュメントを準備するためのコマンドです。これでいつでも元に戻せますね。

use learn;
db.unicorns.remove();
db.unicorns.insert({name: 'Horny', dob: new Date(1992, 2, 13, 7, 47), loves: ['carrot', 'papaya'], weight: 600, gender: 'm', vampires: 63});
db.unicorns.insert({name: 'Aurora', dob: new Date(1991, 0, 24, 13, 0), loves: ['carrot', 'grape'], weight: 450, gender: 'f', vampires: 43});
db.unicorns.insert({name: 'Unicrom', dob: new Date(1973, 1, 9, 22, 10), loves: ['energon', 'redbull'], weight: 984, gender: 'm', vampires: 182});
db.unicorns.insert({name: 'Roooooodles', dob: new Date(1979, 7, 18, 18, 44),loves: ['apple'], weight: 575, gender: 'm', vampires: 99});
db.unicorns.insert({name: 'Solnara', dob: new Date(1985, 6, 4, 2, 1), loves:['apple', 'carrot', 'chocolate'], weight:550, gender:'f', vampires:80});
db.unicorns.insert({name: 'Ayna', dob: new Date(1998, 2, 7, 8, 30), loves: ['strawberry', 'lemon'], weight: 733, gender: 'f', vampires: 40});
db.unicorns.insert({name: 'Kenny', dob: new Date(1997, 6, 1, 10, 42), loves: ['grape', 'lemon'], weight: 690, gender: 'm', vampires: 39});
db.unicorns.insert({name: 'Raleigh', dob: new Date(2005, 4, 3, 0, 57), loves: ['apple', 'sugar'], weight: 421, gender: 'm', vampires: 2});
db.unicorns.insert({name: 'Leia', dob: new Date(2001, 9, 8, 14, 53), loves: ['apple', 'watermelon'], weight: 601, gender: 'f', vampires: 33});
db.unicorns.insert({name: 'Pilot', dob: new Date(1997, 2, 1, 5, 3), loves: ['apple', 'watermelon'], weight: 650, gender: 'm', vampires: 54});
db.unicorns.insert({name: 'Nimue', dob: new Date(1999, 11, 20, 16, 15), loves: ['grape', 'carrot'], weight: 540, gender: 'f'});
db.unicorns.insert({name: 'Dunx', dob: new Date(1976, 6, 18, 18, 18), loves: ['grape', 'watermelon'], weight: 704, gender: 'm', vampires: 165});

db.employees.remove();
db.employees.insert({id: ObjectId("4d85c7039ab0fd70a117d730"), name: 'Leto'})
db.employees.insert({id: ObjectId("4d85c7039ab0fd70a117d731"), name: 'Duncan', manager: ObjectId("4d85c7039ab0fd70a117d730")});
db.employees.insert({id: ObjectId("4d85c7039ab0fd70a117d732"), name: 'Moneo', manager: ObjectId("4d85c7039ab0fd70a117d730")});
db.employees.insert({id: ObjectId("4d85c7039ab0fd70a117d733"), name: 'Siona', manager: [ObjectId("4d85c7039ab0fd70a117d730"), ObjectId("4d85c7039ab0fd70a117d732")]})
db.employees.insert({id: ObjectId("4d85c7039ab0fd70a117d734"), name: 'Ghanima', family: {mother: 'Chani', father: 'Paul', brother: ObjectId("4d85c7039ab0fd70a117d730")}})

 

ダンプ・リストア系

データベースのダンプ

# 全部 
$ mongodump --out ./backups/mongobk_20140801

# 任意のデータベースのみ
$ mongodump --db learn --out ./backups/mongobk_20140801

リストア

$ mongorestore --drop ./backups/mongobk_20140801