MongoDBのチュートリアルをやってみたよ

Open Source Document Database | MongoDBにあるBrowser Shellから、チュートリアルをやってみました。
割と簡単な英語で書いてあって助かる……

チュートリアルはじまりはじまり

Browser Shellに

> tutorial

って打って実行するとチュートリアルの開始。nextを実行すると進んで、backを実行で戻る。

JavaScript Shell

MongoDBのシェルはJavaScriptベースだよー、ってところ。

> a = 5;

> a * 10;

> for (i = 0; i < 10; i++) { print('hello'); };
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello

普通に変数への代入とか演算とか。ついでにループとかですな。

document database

MongoDBはドキュメント指向データベースだよー、ってところ。
JavaScriptのオブジェクトをドキュメントとして保存します、って感じかな?

> var a = {age: 25};
{
  "age": 25
}
> var n = {name: 'Ed', languages: ['c', 'ruby', 'js']};
{
  name: "Ed",
  languages: ["c", "ruby", "js"]
}
> var student = {name: 'Jim', scores: [75, 99, 87.2]};

これだけだとまだオブジェクトを変数に代入しただけだけど……

Saving

保存に関して。

db.scores.save({a: 99});

は「ドキュメント(オブジェクト?){a: 99}をscoresコレクションに保存してね」ってこと。
で、保存したドキュメントを見るには

db.scores.find();

でOKなのです。実際に実行してみると、

> db.scores.save({a: 99});
"ok"
> db.scores.find();
[
  { "a": 99, "_id": { "$oid": "4f858f8fcc93742e0d054905" } }
]

ってな感じ。_idって何かに使ってるんだろうなー。


ちょっと気になるのがdb.scores.find()って実行できちゃうところ。
db.scores = {}; db.scores.find(); とかならわかるんだけど。
ちょっと試してみた。

> typeof db
"object"
> typeof db.scores
"undefined"
> typeof db.scores.find
"function"
> typeof db.scores
"object"
> typeof db.scores.find()
"object"
> db.scores.find()
[

]

……!? typeofでfindに触れたらscoresが生成された?

> typeof db
"object"
> typeof db.aaa
"undefined"
> typeof db.aaa.aaa
"undefined"
> typeof db.aaa.aaa.aaa
JS Error: TypeError: Cannot read proerty 'aaa' of undefined

MongoDBが持ってる関数(ってなんか変な表現だな?)に触れるか、何階層か下までは大丈夫ってことなのかなあ?
でもまあ、データベースとして使うには逆に楽なような気がするけど。

Save and Querying

保存とクエリのところ。

for (i = 0; i < 10; i++) { db.scores.save({a: i, exam: 5}) };

で保存したあと、

db.scores.find();

で検索されて表示される。けど、10個までしか表示されないから、それ以上を表示するためには
itってコマンドでイテレータを実行してげると1個ずつ表示される。


実行すると、

> for (i = 0; i < 10; i++) { db.scores.save({a: i, exam: 5}) };
"ok"
> db.scores.find();
[ 
  {   "a" : 99,   "_id" : {   "$oid" : "4f858f8fcc93742e0d054905"   }   },
  {   "exam" : 5,   "a" : 0,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054907"   }   },
  {   "exam" : 5,   "a" : 3,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054908"   }   },
  {   "exam" : 5,   "a" : 2,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054909"   }   },
  {   "exam" : 5,   "a" : 1,   "_id" : {   "$oid" : "4f858fc6cc93742e0d05490a"   }   },
  {   "exam" : 5,   "a" : 5,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490b"   }   },
  {   "exam" : 5,   "a" : 4,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490c"   }   },
  {   "exam" : 5,   "a" : 6,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490d"   }   },
  {   "exam" : 5,   "a" : 7,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490e"   }   },
  {   "exam" : 5,   "a" : 9,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490f"   }   }
]
> it
[
  {   "exam" : 5,   "a" : 8,   "_id" : {   "$oid" : "4f858fc7cc93742e0d054910"   }   }
]

となる。

Basic Queries

もう少し高度なクエリ発行の仕方。
aが2に一致するドキュメントを検索するには、

db.scores.find({a: 2});

を実行する。
aが15より大きいドキュメントを検索するには、

db.scores.find({a: {'$gt': 15}});

を実行する。


説明通りに実行するとこんな感じ。

> db.scores.find({a: 2});
[ 
  {   "exam" : 5,   "a" : 2,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054909"   }   }
]
> db.scores.find({a: {'$gt': 15}});
[ 
  {   "a" : 99,   "_id" : {   "$oid" : "4f858f8fcc93742e0d054905"   }   }
]

Query Operators

クエリで使えるオペレータについて。
Basic Queriesで使った$gt以外のオペレータにもいろいろあります。

$lt
$lte <=
$gte >=
$ne !=
$in is in array
$nin ! in array

などなど。使い方の例としては、

db.scores.find({a: {'$in': [2, 3, 4]}});
db.scores.find({a: {'$gte': 2, '$lte': 4}});

という感じ。


説明通りに実行してみる。

> db.scores.find({a: {'$in': [2,3,4]}});
[ 
  {   "exam" : 5,   "a" : 3,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054908"   }   },
  {   "exam" : 5,   "a" : 2,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054909"   }   },
  {   "exam" : 5,   "a" : 4,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490c"   }   }
]
> db.scores.find({a: {'$gte': 2, '$lte': 4}});
[ 
  {   "exam" : 5,   "a" : 3,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054908"   }   },
  {   "exam" : 5,   "a" : 2,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054909"   }   },
  {   "exam" : 5,   "a" : 4,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490c"   }   }
]

Updates

ドキュメントの保存について。

db.users.save({name: 'Johnny', languages: ['ruby', 'c']});
db.users.save({name: 'Sue', languages: ['scala', 'lisp']});

saveメソッドにオブジェクトを渡すとそのまま保存されます。
RDBでいうINSERTでいいのかな。


説明通りに実行してみると、

> db.users.save({name: 'Johnny', languages: ['ruby', 'c']});
"ok"
> db.users.save({name: 'Sue', languages: ['scala', 'lisp']});
"ok"
> db.users.find();
[ 
  {   "name" : "Cash",   "_id" : {   "$oid" : "4f8590aecc93742e0d054915"   },   "languages" : [   "english" ]   },
  {   "name" : "Sue",   "_id" : {   "$oid" : "4f8590becc93742e0d054916"   },   "languages" : [   "scala",   "lisp" ]   }
]

こんな感じ。

Update Operators

ドキュメントの更新について。
partial updatesって部分更新、でいいんだっけ?

db.users.update({name: 'Cash'}, {'$set': {'age': 50}});

usersコレクションにあるnameがCashに一致するドキュメントにage: 50を追加、でいいのかな。

db.users.update({name: 'Sue'}, {'$pull': {'languages': 'scala'}});
db.users.update({name: 'Sue'}, {'$push': {'languages': 'ruby'}});

usersコレクションにあるnameがSueに一致するドキュメントのlanguagesにあるscalaを削除、rubyを追加、でいいのかな。


説明通りに実行してみると、

> db.users.update({name: 'Cash'}, {'$set': {'age': 50}});
"ok"
> db.users.update({name: 'Sue'}, {'$pull': {'languages': 'scala'}});
"ok"
> db.users.update({name: 'Sue'}, {'$push': {'languages': 'ruby'}});
"ok"
> db.users.find({name: 'Sue'});
[ 
  {   "name" : "Sue",   "_id" : {   "$oid" : "4f8590becc93742e0d054916"   },
      "languages" : [   "lisp",   "ruby" ]   }
]

こんな感じ。ちゃんと配列から追加・削除できてる。

Deleting data

データの削除について。
nameがSueに一致するドキュメントを削除するには以下のようなクエリを投げる。

db.users.remove({name: 'Sue'});

scoresコレクションのドキュメントをすべて削除するなら以下の通り。

db.scores.remove();


説明通りに実行してみる。

> db.users.remove({name: 'Sue'});
"ok"
> db.users.find();
[ 
  {   "name" : "Cash",   "_id" : {   "$oid" : "4f8590aecc93742e0d054915"   },   "languages" : [   "english" ],   "age" : 50   }
]
> db.scores.find();
[ 
  {   "a" : 99,   "_id" : {   "$oid" : "4f858f8fcc93742e0d054905"   }   },
  {   "exam" : 5,   "a" : 0,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054907"   }   },
  {   "exam" : 5,   "a" : 3,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054908"   }   },
  {   "exam" : 5,   "a" : 2,   "_id" : {   "$oid" : "4f858fc6cc93742e0d054909"   }   },
  {   "exam" : 5,   "a" : 1,   "_id" : {   "$oid" : "4f858fc6cc93742e0d05490a"   }   },
  {   "exam" : 5,   "a" : 5,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490b"   }   },
  {   "exam" : 5,   "a" : 4,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490c"   }   },
  {   "exam" : 5,   "a" : 6,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490d"   }   },
  {   "exam" : 5,   "a" : 7,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490e"   }   },
  {   "exam" : 5,   "a" : 9,   "_id" : {   "$oid" : "4f858fc7cc93742e0d05490f"   }   }
]
> db.scores.remove();
"ok"
> db.scores.find();
[

]

Now go download it!

チュートリアルは終わりだよ、ってところ。
mongodb.orgからドキュメントをチェックアウトしましょーだって。


ついでに、MongoDB Tシャツとかマグカップが当たるとかって書いてある。
emailコレクションにemailフィールド、first_nameフィールド、last_nameフィールドを追加してあげればいいのかな。
しないけど。


なかなか長かった(記事を書くのが)けど、まあまあ楽しかったし、良い記録になったかなー。
JavaScriptで書けるのがとても嬉しい感じ。


このままドキュメントも読んでそれなりに使えるようになりたい。