MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBのクエリ性能を改善する方法:インデックス活用の基本を解説

MongoDBでクエリのフィールド検索を改善するには?

MongoDBで特定フィールドへの検索(クエリ)速度を向上させるには、インデックスを作成することが最も効果的です。インデックスとは、書籍の目次のように、対象フィールドの値とドキュメントの位置情報をあらかじめ整理して保持する仕組みです。これにより、全ドキュメントを順に走査する「コレクションスキャン」を避け、効率的な検索が可能になります。

本記事では、実際にコレクションを作成し、インデックスを追加することでクエリがどのように改善されるのか、具体的な手順をサンプルコード付きで解説します。

1. サンプルコレクションの作成

まず、insertOne()メソッドを使って、プレイヤー情報を持つドキュメントを挿入します。

> db.improveQueryDemo.insertOne(
... {
...     "PlayerDetails":[
...        {"PlayerName": "John", "PlayerGameScore": 5690},
...        {"PlayerName": "Carol", "PlayerGameScore": 2690},
...     ]
... }
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5c9dbaf875e2eeda1d5c3670")
}

この例では、PlayerDetailsという配列フィールドの中に、複数のプレイヤー名(PlayerName)とゲームスコア(PlayerGameScore)を格納したドキュメントを作成しています。

2. 登録済みドキュメントの確認

find()メソッドに.pretty()を組み合わせると、コレクション内のすべてのドキュメントを見やすい整形された形式で表示できます。

> db.improveQueryDemo.find().pretty();

実行結果は以下の通りです。

{
    "_id" : ObjectId("5c9dbaf875e2eeda1d5c3670"),
    "PlayerDetails" : [
       {
          "PlayerName" : "John",
          "PlayerGameScore" : 5690
       },
       {
          "PlayerName" : "Carol",
          "PlayerGameScore" : 2690
       }
    ]
}

3. インデックスの作成

次に、検索対象となる「PlayerDetails.PlayerName」フィールドに対してインデックスを作成します。

> db.improveQueryDemo.ensureIndex({"PlayerDetails.PlayerName":1});

実行結果:

{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

補足: ensureIndex()は現在非推奨となっており、MongoDB 3.0以降ではcreateIndex()の使用が推奨されています。同じ処理は以下のように記述できます。

> db.improveQueryDemo.createIndex({"PlayerDetails.PlayerName":1});

実行結果の「numIndexesBefore : 1」「numIndexesAfter : 2」は、_idフィールドのデフォルトインデックスに加えて、新たに1つのインデックスが追加されたことを示しています。また、値の「1」は昇順(ascending)のインデックスを作成することを意味します。

4. インデックスを活用した検索

インデックスが作成されたので、特定のプレイヤー名で完全一致検索を実行してみましょう。

> db.improveQueryDemo.find({"PlayerDetails.PlayerName":"Carol"}).pretty();

実行結果:

{
    "_id" : ObjectId("5c9dbaf875e2eeda1d5c3670"),
    "PlayerDetails" : [
       {
          "PlayerName" : "John",
          "PlayerGameScore" : 5690
       },
       {
          "PlayerName" : "Carol",
          "PlayerGameScore" : 2690
       }
    ]
}

「Carol」という名前を含むドキュメントが正しく取得できました。データ量が少ないうちは差を実感しにくいですが、数十万件以上の大規模なコレクションでは、インデックスの有無によって検索速度が大きく異なります。

まとめ

  • MongoDBでクエリ性能を改善する基本は、検索対象フィールドへのインデックス作成です。
  • インデックスの作成にはcreateIndex()(旧ensureIndex())を使用します。
  • 配列内のネストされたフィールドにもインデックスを設定できます。
  • explain()メソッドを使えば、クエリが実際にインデックスを利用しているかどうかを確認できます。
  1. MongoDBでオブジェクトの配列フィールドの値をクエリする方法

    MongoDBでは、配列型のフィールドに格納された値を、通常のフィールドと同じように簡単に検索できます。配列内のいずれかの要素が指定した値と一致すれば、そのドキュメントがクエリ結果として返されます。 サンプルコレクションの作成 まず、ドキュメントを含むコレクションを作成しましょう。ここでは「status」という配列フィールドを持つドキュメントを挿入します。 > db.demo295.insertOne({status:[Active,Inactive]}); { acknowledged : true, insertedId : ObjectId(5e4d4ea65d9326

  2. MongoDBコレクション内の空のフィールドをチェックする方法

    MongoDBのコレクション内に空(空文字列)のフィールドが存在するかどうかを調べたい場合、$exists演算子と$eq演算子を組み合わせて使うのが効果的です。この記事では、実際にコレクションを作成しながら、空のフィールドを持つドキュメントを検索する具体的な手順を解説します。 ポイント:$exists と $eq の組み合わせ MongoDBでは「フィールドが存在するが値が空文字列である」状態と、「フィールド自体が存在しない」「値がnullである」状態は区別されます。そのため、空文字列を正確に検索するには次のような条件を使います。 { フィールド名 : { $exists : true, $