【mongoDB】mongoDBチートシート「基本操作」

#RDBとの用語の比較

| RDB | MongoDB | 
|:-----------:|:------------:|
| database     | database        |
| table     | collection  |
| record    | document        |
|column         | field      |
| index     | index       |
| primary key    | _id フィールド    |


macへのインスール　データ保管場所設定

```
brew update
brew upgrade
brew tap mongodb/brew
brew install mongodb-community
sudo mkdir -p /System/Volumes/Data/data/db
sudo chown -R `id -un` /System/Volumes/Data/data/db
```
###起動・状態確認・停止

```
brew services run mongodb-community
brew services list
brew services stop mongodb-community
```
###シェルの実行

```js
mongo
```

#データーベース操作
###データーベースを確認する

```js
show dbs
```

###データーベースを切り替える。（なかったら作成する)

```js
use <データーベース名>
```




###統計情報確認

```js
db.stats()
```
| フィールド名 | 説明 | 
|:-----------:|:------------:|
| collections     | データーベースにあるコレクションの数        |
|dataSize     | 圧縮される前のデータサイズ  |
| strageSize           | コレクションに割り当てられたスペースの合計サイズ。圧縮後のサイズ        |
|indexes        | インデックスの数      |
| indexSize     | インデックスのデータ量の合計       |
| fileSize   |ストレージに保存されるファイルのサイズ   |

###データベースの削除

```js
db.dropDatabase()
```

###データーベース名の変更
※mongodbにはデータベース名を変更する機能はない。
よって、一度別名でコピーして古い方のデーターを削除する。

```js
db.copyDatabase("old_db", "new_db")
use old_db
db.dropDatabase()
```

#コレクションの操作

###データーを挿入する

```js

db.<コレクション>.insertOne(
    {name:"taro", age:30}
    )
```

###全件検索

```js
db.<コレクション>.find()
```

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

```js
show collections
```

###コレクション名の変更

```js
db.old_cl_renameCollection(new_cl, true)
//trueを指定すると古いコレクションが消去される。
```
###コレクションの統計情報

```js
db.collection.stats()
```

| フィールド名 | 説明 | 
|:-----------:|:------------:|
| size     |メモリに展開される合計サイズ        |
|count     | コレクションに入っているデータの件数  |
| storageSize           | ストレージのサイズ       |
|capped   | cappedコケクションかどうかを判定   |
| indexes    | インデックスの数     |
| totalIndexSize   |インデックスのデータ量の合計  |
| IndexSizes   |各インデックスのデータ量   |


###コレクションの削除

```js
db.<コレクション>.drop()
```

###cappedコレクションの作成

```js
db.createColleciton("<コレクション>", {capped: true, size: 1024000}
```

###通常のコレクションをcappedコレクションに変更する。

```js
db.runCommand(
{"convertToCapped":"<コレクション>", size: <サイズの上限> }
)
``` 

#ドキュメントの登録

###一件だけ登録する

```js
db.<コレクション>.insertOne(
  {key1: "value1", key2: "value2"}
  )
```

###複数件登録する

```js
db.<コレクション>.insertMany([
  {key1: "value1", key2: "value3"},
  {key1: "value2", key2: "value5"},
  {key1: "value3", key2: "value6"},
  ])
```

###データ型の登録

```js
db.<コレクション>.insertOne(
  {
   key1: "stringData",
   intdata: NumberLong(1),
   booleanData: true
  }
)
```

###配列・オブジェクトデータの登録

```js
db.<コレクション>.insertOne(
  {
   key1: "taro",
   arrayData:["arr1", "arr2"],
   objData:{obj1: value1, obj2: "value2"}
  }
)
```

#ドキュメントの検索

###検索結果をインデントする。

```js
find().pretty()
```
###条件指定

```js
db.<コレクション>.find(
  {<検索条件>}, //空欄で全件選択
  {key1: 0, key2:1}
)
//0=>非表示　1=>表示
```
###配列の中の要素を指定して検索

```js
db.<コレクション>.find(
  {key1:"value"},
  {"key2.propaty": 1}
)
```

###完全一致

```js
db.<コレクション>.find(
  {key: "value"}
)
```

###部分一致

```js
db.<コレクション>.find(
  {key: "/value/"}
)
```

###前方一致

```js
db.<コレクション>.find(
  {key: "/^value/"}
)
```

###後方一致

```js
db.<コレクション>.find(
  {key: "/value$/"}
)
```

###範囲指定

```js
db.<コレクション>.find(
  {key: {$lte: "value"}}
)
//未満の場合は$lt
//以上の場合は$gte
//より大きいの場合は$gt
//組み合わせることにより、範囲を指定できる。
```

###and・or条件

```js
db.<コレクション>.find(
  { $and:
    [
      {key1: /value$/},
      {key1: /value$/}
    ]
  }
)
//$orでor条件
```

###null検索ついて

nullに関数するデータ型のパターン

```js

① {"user_id":1,"name": ""}
② {"user_id":2, "name": null}
③ {"user_id":3}
④ {"user_id":1, "name": undefined}
```

| 検索条件| 結果 | 
|:-----------:|:------------:|
| ""     |①        |
|null | ②　③　④  |
| $exit:false        | ③      |
|$type:null   | ② |

$typeはnull以外でも使える。また,それぞれデータ型に割り振られた番号でも可。
nullの場合は、10
https://docs.mongodb.com/manual/reference/operator/query/type/

#配列オブジェクトの値で絞り込む

サンプルデータ

collection名　「ff」

```js
//サンプルデータ１
{
	"_id" : ObjectId("5fe7f51d8e92e9609ddd92bd"),
	"name" : "Taro",
	"age" : 20,
	"skill" : [
		"js",
		"php",
		"node",
		"mongo",
		"mysql"
	],
	"child" : [
		{
			"name" : "Jiro",
			"age" : 1
		},
		{
			"name" : "Ken",
			"age" : 3
		}
	]
}

//サンプルデータ２

{
	"_id" : ObjectId("5fe7f7378e92e9609ddd92be"),
	"name" : "Kota",
	"age" : 23,
	"skill" : [
		"aws",
		"docker",
		"linux",
		"git"
	]
}
```

###指定した要素数で検索する

```js
db.ff.find(
  {skill:{$size: 5}},
)
```

###配列の中に、指定した値を全て持つものを検索

```js
db.ff.find(
  {skill: {$all: ["js", "php"]}}
).pretty()
```

###配列の中のオブジェクトで検索

```js
db.ff.find(
    {"child.age":3}
    ).pretty()
{
//オブジェクトの中を検索する場合は、""をつける。
```

###検索結果をソートする

```js
db.ff.find(
  {},
  {_id:0}
  ).sort({ age:1 }) //この場合ageの昇順
//降順は　-1を指定。
```
###取得件数を指定

```js
db.ff.find().limit(2)
```

###件数をスキップして取得。
(この場合は、年齢の小さい二人をのぞいて、残りを取得)

```js
db.ff.find().sort({age: 1})skip(2)
```
#ドキュメントの更新

###一件だけ更新

```js
db.ff.updateOne( 
  {name: "Taro"}, 
  {$set: {age: 40}} 
)

//複数一致する条件があっても最初の一件のみ更新される。
```

###複数件の更新

```js
db.ff.updataMany(
  {age: 20},
  {$set:{"age";21}}
)
//条件を指定しない場合は、全件更新
```

###ドキュメントを丸々入れ替える

```js
db.ff.replaceOne(
  {name: "Taro"},
  {LastName: "Yamada", age:18}
  )
//_idはそのまま。
```

#フィールドを追加する。

###ドキュメントにフィールドを追加

```js
 db.ff.updateOne( 
   {name:"Kota"}, 
   {$set: {height: 170} }
 )
```
###配列に要素を追加する

```js
db.ff.updateOne( 
  {name: "Kota"}, 
  {$set: {"skill.3": "ruby"}} 
)
//オブジェクトを指定しているので""が必要
}
```

###オブジェクトにフィールドを追加する。

```js
db.ff.updateOne( 
  {name:"Taro"}, 
  {$set : {"child.0.gender": "male"}} 
  )
//child配列0番目の要素にgender:"male"を追加
```

###フィールド名を変更する。

```js
db.ff.updateMany(
  {},
  {$rename: {name: "lastName"}
)
```

###データーを登録、または更新

```js
db.ff.updateOne{
  {name: "Taro"},
  {$set: {gender: "male"},
  {upsert: true},
  {multi: true}
)
//upesrt:一致するものがなければ、登録。あれば更新
//multi:条件に合致するもの全て更新するかどうか（指定しなけば一番最初にヒットしたもののみ更新。
```

###ドキュメントを一件削除する

```js
db.ff.deletOne{
  {name: "Taro"}
)
```

###ドキュメントを複数削除する

```js
db.ff.deleteMany{
  {name: "Taro"}
)
```

#node.jsとMongoDB連携

###
サーバー接続(認証なしの場合)

```js

const MongoClient = require('mongodb').MongoClient　//mongodb.MongoClientをロード

let url = 'mongodb://mongo:27017/' //  mongodb://<ホスト>:<ポート>/

const option = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
}

MongoClient.connect(url, option,(error, client) => { //Promiseが返る。
  var db = client.db("sample");//sampleデーターベースをインスタンスか化
  db.createCollection("test", (error, collections) => {//処理の例
    client.close();//切断する。
  });
});

//Promiseが戻り値。
```
#インスタンスに対し処理を行う

##コレクション操作

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

```js
db.cerateCollection("<collectionName>", (error, collections) => {
    client.close();
  })
```
###コレクションの選択

```js
  db.collection("<collectionName>", (error, collections) => {
    client.close();
  })
```
###コレクションを全て取得

```js
db.listCollections().toArray((error, items)=>{ 
  client.close();
})
```

###コレクション名を変更する。

```js
db.renameCollection("old_name", "new_name", (error, collections)=>{
    client.close();
})
//collectionsは新しいコレクションが入っている。
```

###コレクションを削除する。

```js
 db.dropCollection("test_old", (error) => {
    client.close();
  });
```

##ドキュメント操作

###ドキュメントを複数作成
(一件の場合は、insertOneで配列ではなくオブジェクトを渡す)

```js
  //dbはdatabaseをインスタンス化したもの
  db.collection("products", (error, collection) => { //productsコレクションを選択
    collection.insertMany([
      { name: "pen", price: 120 },
      { name: "note", price: 100 }
    ], (error, result) => {
      client.close();
    });
  });
```

###ドキュメントの検索

```js
db.collection("products", (error, collection) => {
    collection
      .find({ name: { $regex: /e/g } }) 
      //colleciton.find({field: {ope:"val"}})
      //promiseでないのでコールバックを呼び出さない。
      .forEach((item) => {
        console.log(item.name);
      }, (error) => {
        client.close();
      });
  });
```
###オペレーターの種類

| ope | 意味 |
|:-:|:-:|
| $eq  |==  |
| $gt | >  |
| $gte  | >= |
| $lt  | <  |
| $lte  | <=  |
| $ne  | !=  |
| $regrex  | 正規表現|

※$eq及び$regrexは省略できる。


###ドキュメントの更新

```js
db.collection("products", (error, collection) => {
    collection.updateMany(
      { name:{$regrex: /e/g }}, 
      //第一引数に対象の選定(完全一致と、正規表現の場合は、$regrex,$eqを省略することができる。)
      { $inc: { price: 20 } }, //$set で置き換え $incは数値が＋される。
      (error, result) => { 
        client.close();
      }
    );
  });
```

###ドキュメントの削除

```js
db.collection("products", (error, collection) => {
    collection.deleteMany(
      { name: /e/g },
      (error, result) => {
        client.close();
      }
    );
  });
```