MongoDBのMapReduceを自席Windows PCで15分で体感する 

この記事は、時間がないけど新しい技術をサクッと吸収したい人向けのものです。
MongoDBのMapReduceを自分のWindows PC１台だけで、インストールから始めて15分で体感することを目指しています。

## ゴール

コマンドプロンプトで、以下のようにMapReduceの結果を表示します。
動物の種類ごとの集計値を得ることができます。

```JavaScript:MapReduceの実行結果
{
        "results" : [
                {
                        "_id" : "cheetah",
                        "value" : {
                                "count" : 10
                        }
                },
                {
                        "_id" : "turtle",
                        "value" : {
                                "count" : 10
                        }
                },
                {
                        "_id" : "zebra",
                        "value" : {
                                "count" : 10
                        }
                }
        ],
        "timeMillis" : 22,
        "counts" : {
                "input" : 30,
                "emit" : 30,
                "reduce" : 3,
                "output" : 3
        },
        "ok" : 1
}
>
```

## 環境
・OS: Windows10 Pro (1803) x64 (日本語版)
・MongoDB: Ver 4.0.0

## 作業の流れ
1. 作業用フォルダの作成
2. MongoDB の導入
3. データ投入
4. MapReduce の実行


## 作業フォルダの作成
これから、ファイルをダウンロードしたりとする作業用フォルダを作成します。この作業は必須ではありませんが、情報の整理という意味では、やっておいた方が良いと思います。

```
C:\sandbox\MongoDBMapReduce
```

## MongoDB の導入
### ダウンロード
MongoDBの以下のダウンロードサイトから以下を選択して、「mongodb-win32-x86_64-2008plus-ssl-4.0.0-signed.msi」を作業フォルダにダウンロードします。
・Version: Windows 64-bit x64
・Installation Package: DOWNLOAD(msi)

https://www.mongodb.com/download-center?jmp=nav#community
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73241/b990e50a-4e15-1dc6-6e76-fca3bd2a16a7.png)

### インストール

ダウンロードした「mongodb-win32-x86_64-2008plus-ssl-4.0.0-signed.msi」をダブルクリックで実行します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/73241/a9933e64-b780-50b5-876d-c4a318e72e45.png)

デフォルトの「Next」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/73241/21217da9-be0f-387a-5b83-d08a37d2faeb.png)

以降、すべてデフォルトで最後まで突き進みます。

### フォルダの作成
以下のフォルダを作成します。

```
C:\sandbox\MongoDBMapReduce\data
C:\sandbox\MongoDBMapReduce\data\db
C:\sandbox\MongoDBMapReduce\data\log
```

### 設定ファイル（mongod.cfg）の作成

インストールされた、以下のファイルを修正します。

```
C:\Program Files\MongoDB\Server\3.2\mongod.cfg
```

※オリジナルのファイルは、必要に応じてコピーしておいてください。

以下の通り変更します。

```yaml:mongod.cfg(修正前)
systemLog:
    destination: file
    path: c:\data\log\mongod.log
storage:
    dbPath: c:\data\db
```

```yaml:mongod.cfg(修正後)
systemLog:
    destination: file
    path: C:\sandbox\MongoDBMapReduce\data\log\mongod.log
storage:
    dbPath: C:\sandbox\MongoDBMapReduce\data\db
```


### mongodの実行
コマンドプロンプトで、インストールしたMongoDBのbinフォルダへ移動して、mongodを実行します。

```
cd C:\Program Files\MongoDB\Server\3.2\bin
mongod
```

以下のように出力され、mongodが起動します。

```
C:\Program Files\MongoDB\Server\3.2\bin>mongod
2018-08-01T12:24:19.271+0900 I CONTROL  [initandlisten] MongoDB starting : pid=13848 port=27017 dbpath=C:\data\db\ 64-bit host=49-OT0087-4
2018-08-01T12:24:19.273+0900 I CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten] db version v3.2.10
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten] git version: 79d9b3ab5ce20f51c272b4411202710a082d0317
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1t-fips  3 May 2016
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten] allocator: tcmalloc
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten] modules: none
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten] build environment:
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten]     distmod: 2008plus-ssl
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten]     distarch: x86_64
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten]     target_arch: x86_64
2018-08-01T12:24:19.274+0900 I CONTROL  [initandlisten] options: {}
2018-08-01T12:24:19.293+0900 I -        [initandlisten] Detected data files in C:\data\db\ created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2018-08-01T12:24:19.295+0900 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=8G,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2018-08-01T12:24:20.333+0900 I NETWORK  [HostnameCanonicalizationWorker] Starting hostname canonicalization worker
2018-08-01T12:24:20.333+0900 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory 'C:/data/db/diagnostic.data'
2018-08-01T12:24:20.363+0900 I NETWORK  [initandlisten] waiting for connections on port 27017
```
### MongoDB shellの実行確認
別のコマンドプロンプトで、インストールしたMongoDBのbinフォルダへ移動して、mongoを実行します。

```
cd C:\Program Files\MongoDB\Server\3.2\bin
mongo
```

以下のように出力されます。

```
C:\Program Files\MongoDB\Server\3.2\bin>mongo
MongoDB shell version: 3.2.10
connecting to: test
```
一旦、MongoDB shell から抜けます。

```
exit
```

### DB作成
「mapreducetest」という名称でDBを作成します。
再び、コマンドプロンプトで、「c:\Program Files\MongoDB\Server\3.2\bin」で、以下のコマンドを実行。

```
mongo mapreducetest
```

その後、MongoDB shell 上で以下を実行。

```
use mapreducetest
show dbs
```

以下のようになります。

```
c:\Program Files\MongoDB\Server\3.2\bin>mongo mapreducetest
MongoDB shell version: 3.2.10
connecting to: mapreducetest
> use mapreducetest
switched to db mapreducetest
> show dbs
local  0.000GB
mydb   0.000GB
```
「show dbs」で、「mapreducetest」が表示されることを期待していたいのに表示されませんね。
次のデータ投入すると、表示されるようになるので、安心してください。

## データ投入
データを投入します。
「animals」というコレクションにドキュメントを追加していきます。
以下の内容をMongoDB shellへコピー&ペーストしてください。

```
db.animals.insert({"type":"cheetah","age":24});
db.animals.insert({"type":"zebra","age":14});
db.animals.insert({"type":"cheetah","age":20});
db.animals.insert({"type":"zebra","age":3});
db.animals.insert({"type":"turtle","age":32});
db.animals.insert({"type":"turtle","age":2});
db.animals.insert({"type":"cheetah","age":24});
db.animals.insert({"type":"zebra","age":14});
db.animals.insert({"type":"cheetah","age":20});
db.animals.insert({"type":"zebra","age":3});
db.animals.insert({"type":"turtle","age":32});
db.animals.insert({"type":"turtle","age":2});
db.animals.insert({"type":"cheetah","age":24});
db.animals.insert({"type":"zebra","age":14});
db.animals.insert({"type":"cheetah","age":20});
db.animals.insert({"type":"zebra","age":3});
db.animals.insert({"type":"turtle","age":32});
db.animals.insert({"type":"turtle","age":2});
db.animals.insert({"type":"cheetah","age":24});
db.animals.insert({"type":"zebra","age":14});
db.animals.insert({"type":"cheetah","age":20});
db.animals.insert({"type":"zebra","age":3});
db.animals.insert({"type":"turtle","age":32});
db.animals.insert({"type":"turtle","age":2});
db.animals.insert({"type":"cheetah","age":24});
db.animals.insert({"type":"zebra","age":14});
db.animals.insert({"type":"cheetah","age":20});
db.animals.insert({"type":"zebra","age":3});
db.animals.insert({"type":"turtle","age":32});
db.animals.insert({"type":"turtle","age":2});
```

以下のように表示されます。

```
> db.animals.insert({"type":"cheetah","age":24});
WriteResult({ "nInserted" : 1 })
> db.animals.insert({"type":"zebra","age":14});
WriteResult({ "nInserted" : 1 })
> db.animals.insert({"type":"cheetah","age":20});
WriteResult({ "nInserted" : 1 })

～ 以降、省略 ～
```

以下を入力して、格納されたデータを確認します。

```
db.animals.find();
```

実際の結果は、以下のようになります。

```

> db.animals.find();
{ "_id" : ObjectId("5b642d16c1c4784ac342eb66"), "type" : "cheetah", "age" : 24 }
{ "_id" : ObjectId("5b642d16c1c4784ac342eb67"), "type" : "zebra", "age" : 14 }

～ 中略 ～
{ "_id" : ObjectId("5b642d16c1c4784ac342eb79"), "type" : "zebra", "age" : 14 }
Type "it" for more
>
```
再び、以下のコマンドでDBの一覧を表示しましょう。

```
show dbs
```

今度は、ちゃんと「mapreducetest」も追加されていますね。

```
> show dbs
local          0.000GB
mapreducetest  0.000GB
mydb           0.000GB
>
```


## MapReduce の実行

MongoDB shellで以降をコピー&ペーストしてください。
map関数、reduce関数を定義して、それを mapReduce()に渡して、MapReduceの結果を得ます。


```JavaScript:MapReduce関数を実行
var map = function() {
  emit(this.type, {count: 1});
};

var reduce = function(key, values) {
  var result = {count: 0};
  values.forEach(function(value) {
    result.count += value.count;
  });
  return result;
};

db.animals.mapReduce(map, reduce, {out: {inline: 1}});
```
結果は、次の通り。

```JavaScript:MapReduceの実行結果
> db.animals.mapReduce(map, reduce, {out: {inline: 1}});
{
        "results" : [
                {
                        "_id" : "cheetah",
                        "value" : {
                                "count" : 10
                        }
                },
                {
                        "_id" : "turtle",
                        "value" : {
                                "count" : 10
                        }
                },
                {
                        "_id" : "zebra",
                        "value" : {
                                "count" : 10
                        }
                }
        ],
        "timeMillis" : 22,
        "counts" : {
                "input" : 30,
                "emit" : 30,
                "reduce" : 3,
                "output" : 3
        },
        "ok" : 1
}
>
```

これで、MapReduceが実行できました！


## 最後に
さて、ここまでで15分でできたでしょうか？
実際にどれぐらい時間がかかったかを教えていただけると、参考になります。

## 参考
[MongoでMapReduceする](https://qiita.com/masahikoofjoyto/items/cd932994234dc0bd1eb6)

[Windows版MongoDBのインストール・MongoShellを通してCRUDコマンドを打ってみる](http://kageura.hatenadiary.jp/entry/2018/01/09/Windows%E7%89%88MongoDB%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%BBMongoShell%E3%82%92%E9%80%9A%E3%81%97%E3%81%A6CRUD%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E6%89%93)

[mongodbでMapReduceをして遊ぶ](http://garicchi.com/?p=20397)

以上