もしノードを再構築するようなことがあればMongoDBインデックスの見直しをお願いします


現在Symbolブロックチェーンはローンチ後、MongoDBのインデックス見直しを行わずに現在に至っています。
一年間の運用を経て、レスポンスが落ちる箇所も出てきました。

現在以下のようなプルリクエストを出していますが、インデックスの反映にはノードの再構築が必要なため、なかなか受け入れられておりません。

https://github.com/fboucquez/symbol-bootstrap/pull/377/commits/6544b783266634809c8c1f04caf8237ad55280f0

もし、お手持ちのノードを0から再構築するようなことがありましたら以下のインデックスを追加して同期をしていただきますよう、ご検討お願いします。

（追記）

@ryosasa さんより、bootstrapを止めずにインデックスを適用する方法を教えていただきました。shコマンドに慣れた方はお試しください。

###### コンテナ起動
```
cd ./target/docker
docker-compose exec db bash 
```

以下のようなエラーメッセージが出ても気にしなくて大丈夫です。

> groups: cannot find name for group ID 1000
I have no name!@2f1cf9a5a41b:/docker-entrypoint-initdb.d

###### インデックス作成
```
mongo --host db
use catapult
db.transactions.createIndex({'transaction.mosaics.id' : 1});
db.transactionStatements.createIndex({'statement.receipts.targetAddress' : 1});
db.transactionStatements.createIndex({'statement.receipts.senderAddress' : 1});
db.transactions.reIndex();
db.transactionStatements.reIndex();
exit
exit
```
以下のようなエラーメッセージが出ても気にしなくて大丈夫です。

> Error saving history file: FileOpenFailed Unable to open() file /.dbshell: Permission denied
I have no name!@2f1cf9a5a41b:/docker-entrypoint-initdb.d

すべてのコマンドにおいて数分間かかると思っておいた方が安心できます。
直接MongoDBを操作しますので、自己責任でお願いします。


(追記ここまで)

### 編集するファイル
target/docker/mongo/mongoDbPrepare.js

### 追加するインデックス

```js
db.transactions.createIndex({ 'transaction.mosaics.id': 1});
```

###### 期待される効果

NFT-DriveやCOMSAのエクスプローラー検索速度が各段に向上します

### 追加するインデックス

```js
db.transactionStatements.createIndex({ 'statement.receipts.targetAddress': 1 });
db.transactionStatements.createIndex({ 'statement.receipts.senderAddress': 1 });
```
###### 期待される効果

XEMBookの表示速度が爆速になります

### 確認方法

反映に成功したかどうやって調べるの？とご指摘いただきましたので、簡単な検証方法をご紹介しておきます。

まず F12で開発者コンソールを開き、ネットワークタブを開いておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/1b9702d2-e130-bde8-d13b-f0db446f9239.png)

次に未適用のノードURLから以下のクエリを指定してアクセスします。

〇NFT-Drive&COMSAなどMosaic転送履歴検索
https://{node url:3001}/transactions/confirmed?embedded=true&transferMosaicId=0F2AFAE62B575AB3

〇XEMBookレシート検索
https://{node url:3001}/statements/transaction?senderAddress=NCESRRSDSXQW7LTYWMHZOCXAESNNBNNVXHPB6WY
https://{node url:3001}/statements/transaction?targetAddress=NCESRRSDSXQW7LTYWMHZOCXAESNNBNNVXHPB6WY

目的の情報を取得するのに所有した時間が出力されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/1f76ffd3-65dc-8ac8-30eb-630ea7bd955e.png)

3.52秒ですね。aws東京リージョンに設置したノードの数値です。

次にインデックスを適用していただいたノードを指定してアクセスしてみてください。

〇NFT-Drive&COMSAなどMosaic転送履歴検索
https://{適用済みnode url:3001}/transactions/confirmed?embedded=true&transferMosaicId=0F2AFAE62B575AB3

〇XEMBookレシート検索
https://{適用済みnode url:3001}/statements/transaction?senderAddress=NCESRRSDSXQW7LTYWMHZOCXAESNNBNNVXHPB6WY
https://{適用済みnode url:3001}/statements/transaction?targetAddress=NCESRRSDSXQW7LTYWMHZOCXAESNNBNNVXHPB6WY

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/dd843b03-0ee1-1294-0786-02369a602664.png)

183msですね。これはアメリカに設置されたノードの数値ですが、爆速改善されたのが分かります。


### bootstrapをアップデートするたびに設定が戻ってしまうのですが

回避策として node_modules配下のbootstrap そのものに変更を行う事で
-- upgrede 後も追加の記述がされる様にする事が出来ます。

```sh
/usr/lib/node_modules/symbol-bootstrap/config/docker/mongo/mongoDbPrepare.js
```
を書き換えると
次に --upgrade すると target 以下にある mongoDbPrepare.js にも変更した状態のが書き写されるようです。

環境によってはbootstrap の格納場所が以下の場所にある場合もあります。

```sh
/usr/local/lib/node_modules/symbol-bootstrap/config/docker/mongo/mongoDbPrepare.js
```

@dusanjp さんにご紹介いただきました。ありがとうございます。


### 他の方法

こちらに MongoDBを直接 db.transactionStatements.reIndex() する方法が紹介されています。
興味のある方はぜひご参考ください。

https://qiita.com/ccHarvestasya/items/2297de63e7d86f6b4d4a

### （追記）MongoDBで反映をちゃんと確認する方法


##### MongoDBへログインしてcatapultデータベースに接続
```sh
$cd target/docker
$docker-compose exec db bash

> mongo --host db
> use catapult
```

##### explain('executionStats')を実行してwinningPlanを確認

"stage" : "COLLSCAN"　となっていれば、フルスキャンです。反映に失敗しています。
"stage" : "IXSCAN"　が表示されていればインデックスが使用されています。

```sh
>db.transactions.find({'transaction.mosaics.id': NumberLong("-6242235878428273386")}).explain('executionStats');


{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "catapult.transactions",
        "indexFilterSet" : false,
        "parsedQuery" : {
                "transaction.mosaics.id" : {
                        "$eq" : NumberLong("-6242235878428273386")
                }
        },
        "winningPlan" : {
                "stage" : "COLLSCAN",
                "filter" : {
                        "transaction.mosaics.id" : {
                                "$eq" : NumberLong("-6242235878428273386")
                        }
                },
                "direction" : "forward"
        },
        "rejectedPlans" : [ ]
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 0,
        "executionTimeMillis" : 72005,
        "totalKeysExamined" : 0,
        "totalDocsExamined" : 6540263,
        "executionStages" : {
                "stage" : "COLLSCAN",
                "filter" : {
                        "transaction.mosaics.id" : {
                                "$eq" : NumberLong("-6242235878428273386")
                        }
                },
                "nReturned" : 0,
                "executionTimeMillisEstimate" : 52198,
                "works" : 6540265,
                "advanced" : 0,
                "needTime" : 6540264,
                "needYield" : 0,
                "saveState" : 7367,
                "restoreState" : 7367,
                "isEOF" : 1,
                "direction" : "forward",
                "docsExamined" : 6540263
        }
    },
    "serverInfo" : {
        "host" : "2f1cf9a5a41b",
        "port" : 27017,
        "version" : "4.4.3",
        "gitVersion" : "913d6b62acfbb344dde1b116f4161360acd8fd13"
    },
    "ok" : 1
}
```