2014-09-03 69 views
0

我有一個測試數據庫錯誤與字段_id,姓名,年齡,日期爲什麼indexOnly屬性對此覆蓋查詢

指標:

[ 
    { 
      "v" : 1, 
      "key" : { 
        "_id" : 1 
      }, 
      "name" : "_id_", 
      "ns" : "blogger.users" 
    }, 
    { 
      "v" : 1, 
      "key" : { 
        "name" : 1, 
        "age" : 1 
      }, 
      "name" : "name_1_age_1", 
      "ns" : "blogger.users" 
    }, 
    { 
      "v" : 1, 
      "key" : { 
        "age" : 1, 
        "name" : 1 
      }, 
      "name" : "age_1_name_1", 
      "ns" : "blogger.users" 
    } 
] 

當運行下面的查詢:

> db.users.find({"name":"user10"},{"_id":0,"date":0}) 
    .explain() 

我得到以下:

{ 
    "cursor" : "BtreeCursor name_1_age_1", 
    "isMultiKey" : false, 
    "n" : 1, 
    "nscannedObjects" : 1, 
    "nscanned" : 1, 
    "nscannedObjectsAllPlans" : 2, 
    "nscannedAllPlans" : 2, 
    "scanAndOrder" : false, 
    "indexOnly" : false, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "millis" : 0, 
    "indexBounds" : { 
      "name" : [ 
        [ 
          "user10", 
          "user10" 
        ] 
      ], 
      "age" : [ 
        [ 
          { 
            "$minElement" : 1 
          }, 
          { 
            "$maxElement" : 1 
          } 
        ] 
      ] 
    }, 
    "server" : "Johny-PC:27017", 
    "filterSet" : false 

}

沒有解釋的結果是:

{ "name" : "user10", "age" : 68 } 

即使這是適當的預測一個覆蓋查詢時,indexOnly領域仍然是假的。我也嘗試使用提示明確提供索引,但沒有改變。在這種情況下,nscannedObjectsAllPlansnscannedAllPlans的值爲1,因爲查詢不嘗試其他索引。

回答

3

對於查詢爲「indexOnly」或「覆蓋」的唯一字段返回必須包含在索引中。所以即使你有一個「name_1_age_1」的索引,查詢引擎仍然期望被「告知」你所需的唯一字段就是索引中的字段。它不知道此有關文檔,直到你檢查它:

db.users.find({"name":"user10"},{"_id":0, "name": 1, "age": 1 }).explain() 

,將返回「indexOnly」作爲查詢引擎知道所選的指數包含了所有所需的輸出字段。因此,如果有其他領域的回報,則無需通過收藏回去。

+0

另外,我已經添加了_id:0的投影。我想這就夠了? – 757071 2014-09-03 05:44:04

+0

@johny不,它不會。您可以隨時「排除」_id,但不能混合和匹配其他字段。這意味着你可以明確包含或排除。不是都。所以'_id'是這裏唯一的例外 – 2014-09-03 05:44:52

+0

現實情況是我實際上排除了一個問題的字段(日期),我認爲這個字段是不相關的。因此,如果我必須排除該鍵,則會顯示此錯誤。 – 757071 2014-09-03 05:49:01