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

MongoDBで$or演算子を含むクエリはインデックスを使用できる?explain()による確認方法を解説

はい、$or演算子を含むクエリでもMongoDBのインデックスを利用できます。重要なのは、$orで指定する各条件のフィールドに対して個別のインデックスを作成しておくことです。インデックスを作成したら、explain()メソッドを使って、クエリが実際にインデックスを使用しているかどうかを確認できます。

1. インデックスの作成

まず、$or条件で使用する各フィールドにインデックスを作成します。なお、ensureIndex()は旧バージョンのメソッドであり、現在のMongoDBではcreateIndex()の使用が推奨されています。

最初のインデックス(Firstフィールド)

> db.indexOrQueryDemo.ensureIndex({"First":1});

実行すると、次のような出力が得られます。

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

2番目のインデックス(Secondフィールド)

続いて、もう一方のフィールドにもインデックスを作成します。

> db.indexOrQueryDemo.ensureIndex({"Second":1});

実行結果:

{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 3,
    "numIndexesAfter" : 4,
    "ok" : 1
}

numIndexesAfterが1つずつ増えていることから、インデックスが正常に追加されたことがわかります。

2. explain()で実行プランを確認する

次に、$or演算子を使ったクエリにexplain()を組み合わせて実行し、インデックスが使用されているかを確認します。

> db.indexOrQueryDemo.find({$or:[{First:1}, {Second:2}]}).explain();

出力される実行プラン(winningPlan)の主要部分は次のとおりです。

{
    "queryPlanner" : {
        "parsedQuery" : {
            "$or" : [
                { "First" : { "$eq" : 1 } },
                { "Second" : { "$eq" : 2 } }
            ]
        },
        "winningPlan" : {
            "stage" : "SUBPLAN",
            "inputStage" : {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "OR",
                    "inputStages" : [
                        {
                            "stage" : "IXSCAN",
                            "keyPattern" : { "First" : 1 },
                            "indexName" : "First_1",
                            "indexBounds" : { "First" : [ "[1.0, 1.0]" ] }
                        },
                        {
                            "stage" : "IXSCAN",
                            "keyPattern" : { "Second" : 1 },
                            "indexName" : "Second_1",
                            "indexBounds" : { "Second" : [ "[2.0, 2.0]" ] }
                        }
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
    "serverInfo" : {
        "host" : "DESKTOP-QN2RB3H",
        "port" : 27017,
        "version" : "4.0.5"
    },
    "ok" : 1
}

3. 実行プランの読み方

この出力から、以下のことが確認できます。

  • SUBPLAN$orクエリ全体の実行プランをまとめるステージです。
  • OR:複数の入力ステージの結果を統合するステージです。
  • IXSCAN:インデックススキャンを表すステージです。indexNameとして「First_1」と「Second_1」の両方が表示されており、作成した2つのインデックスがそれぞれ対応する条件に使われていることがわかります。
  • FETCH:インデックスで特定したドキュメントをコレクションから実際に取り出すステージです。
  • rejectedPlans:空の配列になっており、他により優れた代替プランが存在しなかったことを示しています。

このように、$orクエリの各条件に対応するフィールドへインデックスを作成しておけば、MongoDBは自動的に各ブランチでインデックススキャン(IXSCAN)を実行し、効率的にクエリを処理してくれます。

  1. MongoDBで$or演算子を使ってドキュメントを取得する方法

    MongoDBの$or演算子は、2つ以上の条件式の配列に対して論理OR演算を実行します。配列内のいずれか一つの条件でも一致するドキュメントがあれば、そのドキュメントが検索結果として返されます。この記事では、実際にコレクションを作成し、$or演算子を使ってドキュメントを取得する手順を解説します。サンプルコレクションの作成まず、insertOne()メソッドを使って、ドキュメントを含むコレクションを作成しましょう。 db.demo674.insertOne({Name:John,Age:24}); { acknowledged : true, insertedId : ObjectId

  2. 【MongoDB】ネストされた(入れ子構造の)ドキュメントを更新するクエリの書き方

    MongoDBでは、入れ子(ネスト)になったサブドキュメントのフィールドを更新する際、update()メソッドとドット表記(dot notation)を組み合わせて使用します。ドット表記を使うことで、深い階層にあるフィールドを直接指定して値を変更できます。1. サンプルコレクションの作成まず、ネストされたドキュメントを含むコレクションを作成しましょう。以下のコマンドでdemo607というコレクションにドキュメントを挿入します。> db.demo607.insertOne( ... { ... id: 1, ... Info1 : { ...