MongoDBのCRUD

## MongoDBの動作確認
MongoDBがインストールされているか

```
$ mongo --version
```

サービスが起動しているか（Linux）

```
$ sudo service mongod status
```

## MongoDBの開始

```
$ mongo データベース名
```

データベース名を指定しないとtestというデータベースが作成されます。

```
$ mongo
```

## MongoDBの終了

```
> exit
```

```
> quit()
```

```
Ctrl + C
```

## データベースの作成

```
$ mongo mydb
```

## 全体のヘルプを表示

```
> help
```

## dbメソッドのヘルプ

```
> db.help()
```

## 使用中のデータベースの統計を表示

```
> db.stats()
```

## データベースの一覧を表示

コレクションを作成するまでデータベースは一覧表示されません。

```
> show dbs
```

コレクションを作成する。

```
> db.createCollection('test');
```

```
> show dbs
```

## データベースの切り替え

useコマンドで既存のデータベースに切り替えられます。

```
> use local
```

## データベースの新規作成

useコマンドで存在しないデータベースを指定すると、新規作成されます。

```
> use mydb2
```

## データベースの削除

既存のデータベースに切り替えた後、db.dropDatabase()を実行します。

データベースを切り替える。

```
> use mydb
```

データベース「mydb」を削除。

```
> db.dropDatabase();
```

データベースの確認

```
> show dbs
```


## コレクションの新規作成

```
> show dbs
```

再度データベース「mydb」を作成

```
> use mydb
```

コレクション「users」の作成

```
> db.createCollection('users');
```

## コレクションの一覧表示

```
> show collections
```


## コレクションのリネーム

```
> db.users.renameColection('persons');
```

コレクションを確認

```
> show collections
```

## コレクションの削除

```
> db.persons.drop();
```

コレクションの確認

```
> show collections
```

## ドキュメントの追加

データベースの確認

```
> show dbs
```

データベース「mydb」を使う

```
> use mydb
```

コレクションを確認

```
> show collections
```

コレクション「users」を作成

```
> db.createCollection('users');
```

ドキュメントの挿入

```
> db.users.insert({name:"nakano",score: 30});
```

## ドキュメントの一覧表示

```
> db.users.find();
```

## ドキュメントをスキーマレスに追加

```
> db.users.insert({name:"suzuki",tags:["web","mobile"]});
```

コレクション「users」のドキュメントを全件表示

```
> db.users.find();
```

## ドキュメントを数える

```
> db.users.count();
```

## ドキュメントを削除

コレクション「users」の中の全ドキュメントを削除

```
> db.users.remove();
```

コレクション「users」のドキュメントを確認

```
> db.users.find();
```

## JavaScriptでドキュメントを追加

```js:
> for(var i = 0; i < 4; i++){
    db.users.insert({
        name: "user-" + i,
        team: "team-" + (i % 3),
        score: Math.floor(Math.random() * 100)
    });
}
```

コレクション「users」のドキュメントを確認

```
> db.users.find();
```

## JavaScriptでスキーマレスに追加

```js:
> for(var i = 4; i < 6; i++){
    db.users.insert({
        name: "user-" + i,
        team: "team-" + (i % 3)
    });
}
```

コレクション「users」のドキュメントを確認

```
> db.users.find();
```

## 全件検索

{}の中にWhere句に該当する条件を指定
指定しなければ全件検索

```
> db.users.find({});
```

## nameが"user-1"のドキュメント

```
> db.users.find({name: "user-1"});
```

## nameがuser-1からuser-3のドキュメント

```
> db.users.find({name: /user-[1-3]/});
```

正規表現で検索する

```
> db.users.find({num: {$regex: /[1-3]/i}});
```

## scoreが30より大きい

gt = greater than

```
> db.users.find({score: {$gt: 30}});
```

## scoreが30以上

gte = greater than or equal to

```
> db.users.find({score: {$gte: 30}});
```

## scoreが30より小さい

lt = less than

```
> db.users.find({score: {$lt: 30}});
```

## scoreが30以下

lte = less than or equal to

```
> db.users.find({score: {$lte: 30}});
```

## nameが"user-1"ではないドキュメント

ne = not equal

```
> db.users.find({name: {$ne: "user-1"}});
```

## and検索する

```
> db.users.find({
    team: "team-0",
    score: {$lt: 50}
});
```

## and検索する2

```
> db.users.find({
    $and: [
        {team: "team-0"},
        {score: {$lt: 50}}
    ]
});
```

## or検索する

```
> db.users.find({
    $or: [
        {team: "team-0"},
        {score: {$lt: 50}}
    ]
});
```

## \$in（配列の要素が値に含まれているか）、$exists（キーが存在するか）で検索

```
> db.users.find({
    $or: [
        {team: {$in: ["team-0", "team-1"]}},
        {score: {$exists: true}}
    ]
});
```

## \$nin（配列の要素が値に含まれていないか）、$exists（キーが存在）で検索

nin = not in

```
> db.users.find({
    $or: [
        {team: {$nin: ["team-0", "team-1"]}},
        {score: {$exists: false}}
    ]
});
```

## 重複を削除して検索（teamにどのようなものがあるか）

```
> db.users.distinct('team');
```

## nameキーだけ表示

```
> db.users.find({},{name: 1});
```

## nameキーだけ非表示

```
> db.users.find({},{name: 0});
```

## nameキーとscoreキーのみ表示

```
> db.users.find({},{name: 1, score: 1});
```

## 1と0はミックスできない

エラーになります。

```
> db.users.find({},{name: 1, score: 0});
```

## ただし_idだけ0にすることは可

```
> db.users.find({},{name: 1, _id: 0});
```

## 1件だけ表示

```
> db.users.findOne({}, {_id: 0});
```

## 3件表示

```
> db.users.find({}, {_id: 0}).limit(3);
```

## 2件をスキップして3件表示

```
> db.users.find({}, {_id: 0}).skip(2).limit(3);
```

## scoreの小さい順にソート

```
> db.users.find({}, {_id: 0}).sort({score: 1});
```

## scoreの大きい順にソート

```
> db.users.find({}, {_id: 0}).sort({score: -1});
```

## 索引を確認する

索引をつけると、そのキーでの検索が速くなりますが、追加が遅くなります。

```
> db.users.getIndexes();
```

## 索引を昇順で追加する

```
> db.users.ensureIndex({score: 1});
```

索引を確認する

```
> db.users.getIndexes();
```

## 索引を降順で追加する

```
> db.users.ensureIndex({score: -1});
```

索引を確認する

```
> db.users.getIndexes();
```

## 索引を削除する

```
> db.users.dropIndex({score:1});
```

索引を確認する

```
> db.users.getIndexes();
```

## ユニークキーを追加する

重複するデータを追加するとエラーになります。

```
> db.users.ensureIndex({name:1}, {unique:true});
```

重複するデータを追加してみる

```
> db.users.insert({name: "user-0"});
```

## scoreキーを更新

user-0のドキュメントのがscoreキーだけに更新されます。

```
> db.users.update({name:"user-0"},{score: 100});
```

_idを非表示にして確認

```
> db.users.find({},{_id:0});
```

## scoreキーを更新

user-1のドキュメントのscoreキーの値を更新

```
> db.users.update({name:"user-1"},{$set: {score: 100}});
```

_idを非表示にして確認

```
> db.users.find({},{_id:0});
```

## scoreキーを更新

user-1のドキュメントのscoreキーを削除

```
> db.users.update({name:"user-1"},{$unset: {score: ""}});
```

_idを非表示にして確認

```
> db.users.find({},{_id:0});
```

## scoreキーを更新

user-2のドキュメントのscoreキーを10繰り上げる

```
> db.users.update({name:"user-2"},{$inc: {score: 10}});
```

_idを非表示にして確認

```
> db.users.find({},{_id:0});
```

## scoreキーを更新

user-2のドキュメントのscoreキーを10繰り下げる

```
> db.users.update({name:"user-2"},{$inc: {score: -10}});
```

_idを非表示にして確認

```
> db.users.find({},{_id:0});
```

## scoreキーを更新

user-2のドキュメントのscoreキーをmyscoreキーにリネーム

```
> db.users.update({name:"user-2"},{$rename: {score: "myscore"}});
```

_idを非表示にして確認

```
> db.users.find({},{_id:0});
```

## 複数のドキュメントを更新

コレクション「users」を再構築してドキュメントを挿入

```
db.users.drop();
db.createCollection('users');
for(var i = 0; i < 6; i++){
    db.users.inseert({
        name: "user-" + i,
        team: "team-" + (i % 3),
        score: Math.floor(Math.random() * 100)
    });
}
```

ドキュメントの確認

```
> db.users.find({},{_id:0});
```

このままだとteam-0が2件あっても1件だけしか10繰り上がらない

```
> db.users.update({team: "team-0"}, {$inc: {score: 10}});
```

確認

```
> db.users.find({},{_id:0});
```

team-0のキーを全件10繰り上げるにはmulti

```
> db.users.update({team: "team-0"}, {$inc: {score: 10}}, {multi: true});
```

確認

```
> db.users.find({},{_id:0});
```

## 見つかったら更新、見つからなかったら追加

nameキーの値に"nakano"が見つからないので追加します。

```
> db.users.update({name: "nakano"},{name: "nakano", team: "web", score: 200}, {upsert: true});
```

確認

```
> db.users.find({},{_id:0});
```

nameキーの値に"nakano"が見つかるので更新します。

```
> db.users.update({name: "nakano"},{name: "nakano", team: "web", score: 300}, {upsert: true});
```

確認

```
> db.users.find({},{_id:0});
```

## 特定のキー、値の含まれるドキュメントだけ削除

nameキーの値がnakanoのドキュメントを削除

```
> db.users.remove({name: "nakano"});
```

確認

```
> db.users.find({},{_id:0});
```

## データベースのバックアップ、復元

mongodbを終了してから実行します。dumpディレクトリにバックアップファイルが生成されます。

```
$ mongodump -d mydb;
```

一度変更を加えておいてからmongodbを終了して、復元されるか確認してみます。

データベース「mydb」に接続」

```
mongo mydb
```

ここではteamキーがteam-0のドキュメントを削除しておきます。

```
> db.users.find();
db.users.remove({team: "team-0"});
db.users.find();
exit
```

mongodbを復元します。dumpディレクトリの親ディレクトリから実行します。--dropオプションで既存のデータを削除して復元します。

```
$ mongorestore --drop
```

再度データベース「mydb」に接続して確認してみます。

```
$ mongo mydb
```

確認

```
db.users.find({},{_id:0});
```

バックアップの方法は--helpでヘルプを確認できます。

```
mongodump --help
```

```
mongorestore --help
```