2017-01-28 3 views
1

Es scheint, dass mein Index in meiner MongoDB nicht korrekt ist.

Ich habe 3 Indizes erstellt. Diese:

{ 
    _id: 1 
} 
{ 
    isbn: 1 
} 
{ 
    _id: 1, 
    isbn: 1 
} 

Bei einer Abfrage mit Isbn oder _id funktioniert es perfekt. Auch mit Isbn und _id. Zum Beispiel:

db.getCollection('books').find({ 
    isbn: { 
    $regex: '^978048627.*' 
    }, 
    _id: 'vGXejKQH5kw8Kfutk' 
} 

Bedürfnisse rund um 3ms.

Aber jetzt können sagen, dass ich für eine ISBN suchen möchten und einige _ids ausschließen müssen - ich dies tun:

db.getCollection('books').find({ 
    isbn: { 
    $regex: '^97804862731.*' 
    }, 
    _id: { 
    $nin:['vGXejKQH5kw8Kfutk'] 
    } 
}) 

Nun ist es nicht funktioniert wie es sollte. Die Abfrage dauerte mehr als 10 seconds!

Wenn ich eine isbn Suche ohne $ Regex aber mit $ nin mache funktioniert es perfekt - wieder um 3ms für die Abfrage. Beispiel:

db.getCollection('books').find({ 
    isbn: '9780486273136', 
    _id: { 
    $nin:['vGXejKQH5kw8Kfutk'] 
    } 
}) 

Mache ich etwas falsch? Und warum funktioniert der Index nicht richtig?

Hier ist die .explain() ausgegeben, wenn die 10 Sekunden Abfrage Abfrage:

{ 
    "queryPlanner" : { 
     "plannerVersion" : 1, 
     "namespace" : "***.books", 
     "indexFilterSet" : false, 
     "parsedQuery" : { 
      "$and" : [ 
       { 
        "isbn" : /^97804862731.*/ 
       }, 
       { 
        "$not" : { 
         "_id" : { 
          "$in" : [ 
           "vGXejKQH5kw8Kfutk" 
          ] 
         } 
        } 
       } 
      ] 
     }, 
     "winningPlan" : { 
      "stage" : "FETCH", 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "filter" : { 
        "isbn" : /^97804862731.*/ 
       }, 
       "keyPattern" : { 
        "isbn" : 1.0, 
        "_id" : 1.0 
       }, 
       "indexName" : "isbn_1__id_1", 
       "isMultiKey" : false, 
       "isUnique" : false, 
       "isSparse" : false, 
       "isPartial" : false, 
       "indexVersion" : 1, 
       "direction" : "forward", 
       "indexBounds" : { 
        "isbn" : [ 
         "[\"97804862731\", \"97804862732\")", 
         "[/^97804862731.*/, /^97804862731.*/]" 
        ], 
        "_id" : [ 
         "[MinKey, \"vGXejKQH5kw8Kfutk\")", 
         "(\"vGXejKQH5kw8Kfutk\", MaxKey]" 
        ] 
       } 
      } 
     }, 
     "rejectedPlans" : [ 
      { 
       "stage" : "FETCH", 
       "filter" : { 
        "isbn" : /^97804862731.*/ 
       }, 
       "inputStage" : { 
        "stage" : "IXSCAN", 
        "keyPattern" : { 
         "_id" : 1 
        }, 
        "indexName" : "_id_", 
        "isMultiKey" : false, 
        "isUnique" : true, 
        "isSparse" : false, 
        "isPartial" : false, 
        "indexVersion" : 1, 
        "direction" : "forward", 
        "indexBounds" : { 
         "_id" : [ 
          "[MinKey, \"vGXejKQH5kw8Kfutk\")", 
          "(\"vGXejKQH5kw8Kfutk\", MaxKey]" 
         ] 
        } 
       } 
      }, 
      { 
       "stage" : "FETCH", 
       "filter" : { 
        "$not" : { 
         "_id" : { 
          "$in" : [ 
           "vGXejKQH5kw8Kfutk" 
          ] 
         } 
        } 
       }, 
       "inputStage" : { 
        "stage" : "IXSCAN", 
        "filter" : { 
         "isbn" : /^97804862731.*/ 
        }, 
        "keyPattern" : { 
         "isbn" : 1 
        }, 
        "indexName" : "isbn_1", 
        "isMultiKey" : false, 
        "isUnique" : true, 
        "isSparse" : false, 
        "isPartial" : false, 
        "indexVersion" : 1, 
        "direction" : "forward", 
        "indexBounds" : { 
         "isbn" : [ 
          "[\"97804862731\", \"97804862732\")", 
          "[/^97804862731.*/, /^97804862731.*/]" 
         ] 
        } 
       } 
      } 
     ] 
    }, 
    "serverInfo" : { 
     "host" : "Ubuntu-1604-xenial-64-minimal", 
     "port" : 27017, 
     "version" : "3.2.11", 
     "gitVersion" : "009580ad490190ba33d1c6253ebd8d91808923e4" 
    }, 
    "ok" : 1.0 
} 

Antwort

1

Lösung

Meine Lösung - ich weiß nicht, warum - aber ist $ zu verwenden und und $ ne statt $ nin.

Meine Frage wie folgt aussieht jetzt:

db.getCollection('books').find({isbn:{$regex: '^97804862731.*'}, $and: [ 
    { 
    _id: { 
     $ne: 'vGXejKQH5kw8Kfutk' 
    } 
    }, 
    { 
    _id: { 
     $ne: 'another-id' 
    } 
    } 
]}) 

und dauert nur um 3ms

Vielleicht kann jemand erklären, wie das passieren kann?

Der erklären() dieser Abfrage

{ 
    "queryPlanner" : { 
     "plannerVersion" : 1, 
     "namespace" : "***.books", 
     "indexFilterSet" : false, 
     "parsedQuery" : { 
      "$and" : [ 
       { 
        "isbn" : /^97804862731.*/ 
       }, 
       { 
        "$not" : { 
         "_id" : { 
          "$eq" : "vGXejKQH5kw8Kfutk" 
         } 
        } 
       }, 
       { 
        "$not" : { 
         "_id" : { 
          "$eq" : "another-id" 
         } 
        } 
       } 
      ] 
     }, 
     "winningPlan" : { 
      "stage" : "FETCH", 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "filter" : { 
        "isbn" : /^97804862731.*/ 
       }, 
       "keyPattern" : { 
        "isbn" : 1.0, 
        "_id" : 1.0 
       }, 
       "indexName" : "isbn_1__id_1", 
       "isMultiKey" : false, 
       "isUnique" : false, 
       "isSparse" : false, 
       "isPartial" : false, 
       "indexVersion" : 1, 
       "direction" : "forward", 
       "indexBounds" : { 
        "isbn" : [ 
         "[\"97804862731\", \"97804862732\")", 
         "[/^97804862731.*/, /^97804862731.*/]" 
        ], 
        "_id" : [ 
         "[MinKey, \"another-id\")", 
         "(\"another-id\", \"vGXejKQH5kw8Kfutk\")", 
         "(\"vGXejKQH5kw8Kfutk\", MaxKey]" 
        ] 
       } 
      } 
     }, 
     "rejectedPlans" : [ 
      { 
       "stage" : "FETCH", 
       "filter" : { 
        "isbn" : /^97804862731.*/ 
       }, 
       "inputStage" : { 
        "stage" : "IXSCAN", 
        "keyPattern" : { 
         "_id" : 1 
        }, 
        "indexName" : "_id_", 
        "isMultiKey" : false, 
        "isUnique" : true, 
        "isSparse" : false, 
        "isPartial" : false, 
        "indexVersion" : 1, 
        "direction" : "forward", 
        "indexBounds" : { 
         "_id" : [ 
          "[MinKey, \"another-id\")", 
          "(\"another-id\", \"vGXejKQH5kw8Kfutk\")", 
          "(\"vGXejKQH5kw8Kfutk\", MaxKey]" 
         ] 
        } 
       } 
      }, 
      { 
       "stage" : "FETCH", 
       "filter" : { 
        "$and" : [ 
         { 
          "$not" : { 
           "_id" : { 
            "$eq" : "vGXejKQH5kw8Kfutk" 
           } 
          } 
         }, 
         { 
          "$not" : { 
           "_id" : { 
            "$eq" : "another-id" 
           } 
          } 
         } 
        ] 
       }, 
       "inputStage" : { 
        "stage" : "IXSCAN", 
        "filter" : { 
         "isbn" : /^97804862731.*/ 
        }, 
        "keyPattern" : { 
         "isbn" : 1 
        }, 
        "indexName" : "isbn_1", 
        "isMultiKey" : false, 
        "isUnique" : true, 
        "isSparse" : false, 
        "isPartial" : false, 
        "indexVersion" : 1, 
        "direction" : "forward", 
        "indexBounds" : { 
         "isbn" : [ 
          "[\"97804862731\", \"97804862732\")", 
          "[/^97804862731.*/, /^97804862731.*/]" 
         ] 
        } 
       } 
      } 
     ] 
    }, 
    "serverInfo" : { 
     "host" : "Ubuntu-1604-xenial-64-minimal", 
     "port" : 27017, 
     "version" : "3.2.11", 
     "gitVersion" : "009580ad490190ba33d1c6253ebd8d91808923e4" 
    }, 
    "ok" : 1.0 
} 
+1

können Sie auch die '.explain()' Ausgang für diese Abfrage enthalten? – chridam

Verwandte Themen