2012-10-08 84 views
2

這是我的文件,我想查詢:如何索引我的收藏使用複合多鍵索引

{ 
"_id":ObjectId("5062d30522dfae0e11000000"), 
"id_resource" : "147", 
"moment_created" : ISODate("2012-03-22T16:29:21Z"), 
"moment_updated" : ISODate("2012-03-22T16:29:21Z"), 
"users_involved" : [ 
    { 
     "id_user" : "113928869", 
     "state" : "answered", 
     "id_folder" : "0", 
     "is_deleted" : "0" 
    }, 
    { 
     "id_user" : "121624627", 
     "state" : "new", 
     "id_folder" : "0", 
     "is_deleted" : "0" } 
], 
"posts" : [ 
    { 
     "id_author" : "113928869", 
     "post" : "hiohhio", 
     "moment_created" : ISODate("2012-03-22T16:29:21Z") 
    } 
    ] 
} 

,這是我努力確保我的索引:

db.message.ensureIndex({id_resource:1, users_involved : 1}); 

這是我用來查詢我的收藏查詢:

db.message.find({id_resource : "143", "users_involved" : {$elemMatch : {id_user : "101226353", state : "answered"}}}); 

但一人後來解釋我得到這個輸出:

{ 
    "clusteredType" : "ParallelSort", 
    "cursor" : "BasicCursor", 
    "n" : 11, 
    "nChunkSkips" : 0, 
    "nYields" : 8624, 
    "nscanned" : 1461277, 
    "nscannedAllPlans" : 1461277, 
    "nscannedObjects" : 1461277, 
    "nscannedObjectsAllPlans" : 1461277, 
    "millisShardTotal" : 1878, 
    "millisShardAvg" : 939, 
    "numQueries" : 2, 
    "numShards" : 2, 
    "millis" : 1646 

}

getIndexes將返回:

[ 
    { 
      "v" : 1, 
      "key" : { 
        "_id" : 1 
      }, 
      "ns" : "messaging.message", 
      "name" : "_id_" 
    }, 
    { 
      "v" : 1, 
      "key" : { 
        "id_resource" : 1, 
        "users_involved" : 1 
      }, 
      "ns" : "messaging.message", 
      "name" : "id_resource_1_users_involved_1" 
    } 

]

可悲的是,爲什麼我的查詢不使用索引id_resource_1_users_involved_1我不明白。任何人都可以向我解釋爲什麼我的索引不被使用,或者我如何構建我的索引以支持我想要使用的查詢?

THX的時間,並幫助了我

UPDATE

恥辱,在我身邊一個錯字。因此,這裏的實際查詢

{ 
    "clusteredType" : "ParallelSort", 
    "cursor" : "BtreeCursor id_resource_1_users_involved_1", 
    "n" : 5, 
    "nChunkSkips" : 0, 
    "nYields" : 2, 
    "nscanned" : 46868, 
    "nscannedAllPlans" : 93736, 
    "nscannedObjects" : 46868, 
    "nscannedObjectsAllPlans" : 93736, 
    "millisShardTotal" : 281, 
    "millisShardAvg" : 140, 
    "numQueries" : 2, 
    "numShards" : 2, 
    "millis" : 220 

}

所以查詢使用我的索引,但它仍然是緩慢的解釋,也nscanned是相當大的,所以不使用整個索引?我將不得不檢查nscanned匹配使用複合指數從JohnnyHK資源X

消息也得到了很多快得多量:

ensureIndex({id_resource:1, 'users_involved.id_user':1, 'users_involved.state':1}); 

解釋

{ 
    "clusteredType" : "ParallelSort", 
    "cursor" : "BtreeCursor id_resource_1_users_involved.id_user_1_users_involved.state_1", 
    "n" : 5, 
    "nChunkSkips" : 0, 
    "nYields" : 0, 
    "nscanned" : 7, 
    "nscannedAllPlans" : 7, 
    "nscannedObjects" : 7, 
    "nscannedObjectsAllPlans" : 7, 
    "millisShardTotal" : 0, 
    "millisShardAvg" : 0, 
    "numQueries" : 2, 
    "numShards" : 2, 
    "millis" : 1 
} 

所以,如果我想要查詢users_involved數組我必須爲每個查詢建立一個單獨的索引?

採用全陣列還@JohnnyHK像提到:

find({id_resource : "197", "users_involved" : {$elemMatch : {id_user : "128825371", state : "answered", id_folder:"0", is_deleted:"0"}}}).hint("id_resource_1_users_involved_1") 

沒有改善什麼,解釋:

{ 
    "clusteredType" : "ParallelSort", 
    "cursor" : "BtreeCursor id_resource_1_users_involved_1", 
    "n" : 5, 
    "nChunkSkips" : 0, 
    "nYields" : 1, 
    "nscanned" : 46868, 
    "nscannedAllPlans" : 46868, 
    "nscannedObjects" : 46868, 
    "nscannedObjectsAllPlans" : 46868, 
    "millisShardTotal" : 222, 
    "millisShardAvg" : 111, 
    "numQueries" : 2, 
    "numShards" : 2, 
    "millis" : 174 

}

或者也許我還是做錯了?

*也我刪除從解釋響應碎片信息,如果該信息可能是重要的只是說所以

回答

1

因爲你的化合物索引包括整個users_involved陣列,只能使用的折射率匹配完整的嵌入式文檔時數組的元素。見here

我想你會更好地服務使用複合索引,其中只包括您打算搜索的users_involved的字段。因此,要麼:

db.message.ensureIndex({id_resource:1, 'users_involved.id_user' : 1}); 

OR

db.message.ensureIndex({id_resource:1, 'users_involved.id_user' : 1, 'users_involved.state' : 1}); 
+0

THX您的幫助,您可以檢查我的更新? – braunbaer

+0

@braunbaer您不必爲每個查詢構建單獨的索引,但需要確保您定義的索引提供了足夠的選擇性,以便在任何給定查詢中只需掃描少數文檔。請參閱複合鍵上的[docs](http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeys)。 – JohnnyHK

+0

好吧,每一個新的案例(查詢)將是一個新的索引。 情況下 「資源X遊戲者Y夾Z」 - >索引resource_player_folder 情況下 「資源X遊戲者Y狀態Z」 - >索引resource_player_state 情況下 「資源X玩家X文件夾Z狀態XZ」 - >索引resource_player_state_folder 的想法是通過「users_invovled」創建一個索引,而對於幾乎相同的查詢沒有這些分離的索引。但也許我只需要多次閱讀文檔以真正理解它們。 Thx爲您的時間和幫助。 – braunbaer