2016-08-17 8 views
2

mongodbでindiceを使用してクエリを作成する必要があります。私は実際のケースの最小例を示します。

私が流れるデータを収集し、次います

devsrv(mongod-3.0.4) test> db.teste.find() 
{ 
    "_id": ObjectId("57b324c341aaa4b930ef3b92"), 
    "a": 1, 
    "b": 1 
} 
{ 
    "_id": ObjectId("57b324c941aaa4b930ef3b93"), 
    "a": 1, 
    "b": 2 
} 
{ 
    "_id": ObjectId("57b324cd41aaa4b930ef3b94"), 
    "a": 1, 
    "b": 3 
} 
{ 
    "_id": ObjectId("57b324d141aaa4b930ef3b95"), 
    "a": 1, 
    "b": 4 
} 
{ 
    "_id": ObjectId("57b324d541aaa4b930ef3b96"), 
    "a": 1, 
    "b": 5 
} 
{ 
    "_id": ObjectId("57b324da41aaa4b930ef3b97"), 
    "a": 1, 
    "b": 6 
} 
{ 
    "_id": ObjectId("57b324df41aaa4b930ef3b98"), 
    "a": 1, 
    "b": 7 
} 
{ 
    "_id": ObjectId("57b324e441aaa4b930ef3b99"), 
    "a": 1, 
    "b": 8 
} 
{ 
    "_id": ObjectId("57b324f341aaa4b930ef3b9a"), 
    "a": 1, 
    "b": "" 
} 
{ 
    "_id": ObjectId("57b324f641aaa4b930ef3b9b"), 
    "a": 1, 
    "b": " " 
} 
{ 
    "_id": ObjectId("57b324fc41aaa4b930ef3b9c"), 
    "a": 1, 
    "b": null 
} 
{ 
    "_id": ObjectId("57b3250341aaa4b930ef3b9d"), 
    "a": 1 
} 
{ 
    "_id": ObjectId("57b46ace41aaa4b930ef3b9e"), 
    "a": 2 
} 

そして、私持って次のインデックス:

devsrv(mongod-3.0.4) test> db.teste.getIndexes() 
[ 
    { 
    "v": 1, 
    "key": { 
     "_id": 1 
    }, 
    "name": "_id_", 
    "ns": "test.teste" 
    }, 
    { 
    "v": 1, 
    "key": { 
     "a": 1, 
     "b": 1 
    }, 
    "name": "a_1_b_1", 
    "ns": "test.teste" 
    }, 
    { 
    "v": 1, 
    "key": { 
     "b": 1 
    }, 
    "name": "b_1", 
    "ns": "test.teste" 
    } 
] 

そして、私は同じクエリを行う必要がある。この:

devsrv(mongod-3.0.4) test> db.teste.find({$or:[{"b":null},{"b":""},{"b":" "},{"b":{$lt:3}}],"a":1}).explain("executionStats") 
{ 
    "queryPlanner": { 
    "plannerVersion": 1, 
    "namespace": "test.teste", 
    "indexFilterSet": false, 
    "parsedQuery": { 
     "$and": [ 
     { 
      "$or": [ 
      { 
       "b": { 
       "$eq": null 
       } 
      }, 
      { 
       "b": { 
       "$eq": "" 
       } 
      }, 
      { 
       "b": { 
       "$eq": " " 
       } 
      }, 
      { 
       "b": { 
       "$lt": 3 
       } 
      } 
      ] 
     }, 
     { 
      "a": { 
      "$eq": 1 
      } 
     } 
     ] 
    }, 
    "winningPlan": { 
     "stage": "FETCH", 
     "filter": { 
     "a": { 
      "$eq": 1 
     } 
     }, 
     "inputStage": { 
     "stage": "FETCH", 
     "filter": { 
      "$or": [ 
      { 
       "b": { 
       "$eq": null 
       } 
      }, 
      { 
       "b": { 
       "$eq": "" 
       } 
      }, 
      { 
       "b": { 
       "$eq": " " 
       } 
      }, 
      { 
       "b": { 
       "$lt": 3 
       } 
      } 
      ] 
     }, 
     "inputStage": { 
      "stage": "IXSCAN", 
      "keyPattern": { 
      "b": 1 
      }, 
      "indexName": "b_1", 
      "isMultiKey": false, 
      "direction": "forward", 
      "indexBounds": { 
      "b": [ 
       "[null, null]", 
       "[-inf.0, 3.0)", 
       "[\"\", \"\"]", 
       "[\" \", \" \"]" 
      ] 
      } 
     } 
     } 
    }, 
    "rejectedPlans": [ 
     { 
     "stage": "FETCH", 
     "filter": { 
      "$or": [ 
      { 
       "b": { 
       "$eq": null 
       } 
      }, 
      { 
       "b": { 
       "$eq": "" 
       } 
      }, 
      { 
       "b": { 
       "$eq": " " 
       } 
      }, 
      { 
       "b": { 
       "$lt": 3 
       } 
      } 
      ] 
     }, 
     "inputStage": { 
      "stage": "IXSCAN", 
      "keyPattern": { 
      "a": 1, 
      "b": 1 
      }, 
      "indexName": "a_1_b_1", 
      "isMultiKey": false, 
      "direction": "forward", 
      "indexBounds": { 
      "a": [ 
       "[1.0, 1.0]" 
      ], 
      "b": [ 
       "[MinKey, MaxKey]" 
      ] 
      } 
     } 
     } 
    ] 
    }, 
    "executionStats": { 
    "executionSuccess": true, 
    "nReturned": 6, 
    "executionTimeMillis": 0, 
    "totalKeysExamined": 8, 
    "totalDocsExamined": 14, 
    "executionStages": { 
     "stage": "FETCH", 
     "filter": { 
     "a": { 
      "$eq": 1 
     } 
     }, 
     "nReturned": 6, 
     "executionTimeMillisEstimate": 0, 
     "works": 10, 
     "advanced": 6, 
     "needTime": 2, 
     "needFetch": 0, 
     "saveState": 0, 
     "restoreState": 0, 
     "isEOF": 1, 
     "invalidates": 0, 
     "docsExamined": 7, 
     "alreadyHasObj": 7, 
     "inputStage": { 
     "stage": "FETCH", 
     "filter": { 
      "$or": [ 
      { 
       "b": { 
       "$eq": null 
       } 
      }, 
      { 
       "b": { 
       "$eq": "" 
       } 
      }, 
      { 
       "b": { 
       "$eq": " " 
       } 
      }, 
      { 
       "b": { 
       "$lt": 3 
       } 
      } 
      ] 
     }, 
     "nReturned": 7, 
     "executionTimeMillisEstimate": 0, 
     "works": 8, 
     "advanced": 7, 
     "needTime": 1, 
     "needFetch": 0, 
     "saveState": 0, 
     "restoreState": 0, 
     "isEOF": 1, 
     "invalidates": 0, 
     "docsExamined": 7, 
     "alreadyHasObj": 0, 
     "inputStage": { 
      "stage": "IXSCAN", 
      "nReturned": 7, 
      "executionTimeMillisEstimate": 0, 
      "works": 8, 
      "advanced": 7, 
      "needTime": 1, 
      "needFetch": 0, 
      "saveState": 0, 
      "restoreState": 0, 
      "isEOF": 1, 
      "invalidates": 0, 
      "keyPattern": { 
      "b": 1 
      }, 
      "indexName": "b_1", 
      "isMultiKey": false, 
      "direction": "forward", 
      "indexBounds": { 
      "b": [ 
       "[null, null]", 
       "[-inf.0, 3.0)", 
       "[\"\", \"\"]", 
       "[\" \", \" \"]" 
      ] 
      }, 
      "keysExamined": 8, 
      "dupsTested": 0, 
      "dupsDropped": 0, 
      "seenInvalidated": 0, 
      "matchTested": 0 
     } 
     } 
    } 
    }, 
    "serverInfo": { 
    "host": "devsrv", 
    "port": 27017, 
    "version": "3.0.4", 
    "gitVersion": "0481c958daeb2969800511e7475dc66986fa9ed5" 
    }, 
    "ok": 1 
} 

しかし、 MongoDBは2つのインデックスを一緒に使用していません。クエリオプティマイザは、すべての適切なインデックスとクエリの実際の性能を測定することにより、最も効率的なクエリを選択するよう

+0

誰かがmongoに2つのインデックスを使用させる方法を教えてくれますか? –

答えて

0

$orという用語は事実上別のクエリです。したがって、各用語が使用する予定のインデックスと一致するようにクエリを構造化するのに役立ちます。各$or用語の内部a: 1一部を移動させる手段、この場合:

db.teste.find({ 
    $or:[ 
    {a: 1, b: null}, 
    {a: 1, b: ""}, 
    {a: 1, b: " "}, 
    {a: 1, b: {$lt: 3}} 
    ]}).explain('executionStats') 

説明出力​​このクエリのために使用されることを示しています。

しかし、あなたが一つに最初の3つの用語を組み合わせること$inを使用することによって、このビット以上を簡素化することができます。

db.teste.find({ 
    $or:[ 
    {a: 1, b: {$in: [null, "", " "]}}, 
    {a: 1, b: {$lt: 3}} 
    ]}).explain('executionStats') 

これも​​インデックスを使用することができます。

+0

実際には、このパラメータはdinamicのクエリからのものです –

0

コードが

db.teste.explain("executionStats").find({a: 1, 
             $or:[{b: null}, 
               {b: ""}, 
               {b: " "}, 
               {b: {$lt:3}}] 
             }).hint({a: 1, b: 1}) 

ではhintコマンドに注意してください。

+0

非常によくこれは、おかげで助けることができます! –

+0

@DimiAntoniVargasあなたの問題を解決する答えを受け入れることは良い習慣です:-) – BVengerov

関連する問題