2016-04-08 6 views
2

Ich führe eine Abfrage mit $ elemMatch aus und es scheint, als ob sie nicht den Index verwendet, den ich dafür hinzugefügt habe.

Hier ist mein Dokument:

{ 
    "_id" : "123466", 
    "something" : [ 
     { 
     "someID" : ObjectId("5701b4c3c6b126083332e66f"), 
     "tags": 
     [ 
      { 
      "tagKey": "ErrorCode", 
      "tagValue": "7001" 
      }, 
      { 
      "tagKey": "ErrorDescription", 
      "tagValue": "nullPointer" 
      } 
     ], 
     "removeOnDelivery" : true, 
     "entryTime" : ISODate("2016-04-04T00:26:43.167Z") 
    } 
    ] 
} 

Hier sind die Indizes ich verwende (I soll nur der erste Index verwenden, aber ich hinzugefügt, um zusätzliche Indizes zu untersuchen, warum keiner von ihnen arbeiten).

db.test.createIndex({ "something.tags:" : 1 }, { sparse : true, background : true }) 
db.test.createIndex({ "something.tags.tagKey:" : 1 }, { sparse : true, background : true }) 
db.test.createIndex({ "something.tags.tagValue:" : 1 }, { sparse : true, background : true }) 
db.test.createIndex({ "something.tags.tagKey:" : 1, "something.tags.tagValue:" : 1 }, { sparse : true, background : true }) 

Hier ist meine Frage und Antwort:

db.test.find({"something.tags": { $elemMatch: { "tagKey" : "ErrorCode", "tagValue" : "7001" } } }).explain() 

{ 
    "cursor": "BasicCursor", 
    "isMultiKey": false, 
    "n": 2, 
    "nscannedObjects": 2, 
    "nscanned": 2, 
    "nscannedObjectsAllPlans": 2, 
    "nscannedAllPlans": 2, 
    "scanAndOrder": false, 
    "indexOnly": false, 
    "nYields": 0, 
    "nChunkSkips": 0, 
    "millis": 0, 
    "server": "some_server", 
    "filterSet": false, 
    "stats": { 
     "type": "COLLSCAN", 
     "works": 4, 
     "yields": 0, 
     "unyields": 0, 
     "invalidates": 0, 
     "advanced": 2, 
     "needTime": 1, 
     "needFetch": 0, 
     "isEOF": 1, 
     "docsTested": 2, 
     "children": [] 
    } 
} 
+1

Welche Server-Version? Sieht nach einem Ergebnis der 2.6.x-Serie aus. Beachten Sie, dass es nur 2 Dokumente in der Sammlung gibt, so dass der Planer wahrscheinlich nur einen Screenshot für einen Sammlungsscan erstellt. –

Antwort

3

Ich weiß nicht, ob dies ein Tippfehler war. Ihre createIndex-Abfrage hat : am Ende des Indexnamens. Wenn Sie das korrigieren, erhalten Sie möglicherweise die gewünschten Ergebnisse.

Es ist jedoch nicht notwendig, dass der Gewinnplan immer den mit Index verwendet. Wenn COLLSCAN billiger ist, was bei Sammlungen mit weniger Elementen der Fall sein kann, kann Mongo COLLSCAN wählen.

Wenn Sie die Indexnutzung erzwingen möchten, können Sie .hint ("index_name") verwenden.

Ich versuchte mit dem richtigen Indexnamen ohne : in Namen und Index verwendet, um abzufragen. Ihre Ergebnisse können abhängig von der Sammlungsstatistik und der Serverversion, wie in den Kommentaren von @Neil Lunn erwähnt, unterschiedlich sein.

db.test.createIndex({ "something.tags.tagKey" : 1 }, { sparse : true, background : true }) 

und Ergebnisse erklären,

db.test.find({"something.tags": { $elemMatch: { "tagKey" : "ErrorCode"} } }).explain() 


{ 
    "queryPlanner" : { 
     "plannerVersion" : 1, 
     "namespace" : "test_db.test", 
     "indexFilterSet" : false, 
     "parsedQuery" : { 
      "something.tags" : { 
       "$elemMatch" : { 
        "tagKey" : { 
         "$eq" : "ErrorCode" 
        } 
       } 
      } 
     }, 
     "winningPlan" : { 
      "stage" : "FETCH", 
      "filter" : { 
       "something.tags" : { 
        "$elemMatch" : { 
         "tagKey" : { 
          "$eq" : "ErrorCode" 
         } 
        } 
       } 
      }, 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "keyPattern" : { 
        "something.tags.tagKey" : 1 
       }, 
       "indexName" : "something.tags.tagKey_1", 
       "isMultiKey" : true, 
       "isUnique" : false, 
       "isSparse" : true, 
       "isPartial" : false, 
       "indexVersion" : 1, 
       "direction" : "forward", 
       "indexBounds" : { 
        "something.tags.tagKey" : [ 
         "[\"ErrorCode\", \"ErrorCode\"]" 
        ] 
       } 
      } 
     }, 
     "rejectedPlans" : [ ] 
    }, 

    "ok" : 1 
} 
+0

Ja, ** aber ** Sie führen dies auf einem Server der 3.x-Serie aus. Der Abfrageoptimierer führt in verschiedenen Versionen unterschiedliche Aktionen aus. Sie können sagen, dass eine 2.6.x-Reihe mit dem "filterSet" in der Ausgabe verwendet wird. –

+0

Ja. Du hast recht und danke für den Hinweis zu "filterSet". Ich könnte etwas Neues lernen. – nobody

+0

Danke Jungs. Ja das war nicht beabsichtigt. – Sachin

Verwandte Themen