2012-10-11 26 views
3

慢我有這樣的文檔結構:MongoDB的查詢與點符號

{ 
    "key": { 
    "a": Int32, 
    "b": String 
    } 
} 

key.akey.bkey和索引(非唯一)的唯一指標。

然而,這個查詢掃描(slooow):

{"key.a": 456213154} 

與此查詢不:

{"key": { 
    "a": 456213154, 
    "b": {"$exists": true} 
}} 

爲什麼是必要的,而且應該是什麼?

(我應該指出,這是V2.0.3)

編輯:加入解釋:

> db.collection.find({"key.a": 456213154}).explain() 
{ 
     "cursor" : "BtreeCursor key.a_1", 
     "nscanned" : 10962, 
     "nscannedObjects" : 10962, 
     "n" : 10962, 
     "millis" : 20, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "isMultiKey" : false, 
     "indexOnly" : false, 
     "indexBounds" : { 
       "key.a" : [ 
         [ 
           456213154, 
           456213154 
         ] 
       ] 
     } 
} 
> db.collection.find({"key": {"a": 456213154, "b": {"$exists":true}}}).explain() 
{ 
     "cursor" : "BtreeCursor key_1", 
     "nscanned" : 0, 
     "nscannedObjects" : 0, 
     "n" : 0, 
     "millis" : 0, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "isMultiKey" : false, 
     "indexOnly" : false, 
     "indexBounds" : { 
       "key" : [ 
         [ 
           { 
             "a" : 456213154, 
             "b" : { 
               "$exists" : true 
             } 
           }, 
           { 
             "a" : 456213154, 
             "b" : { 
               "$exists" : true 
             } 
           } 
         ] 
       ] 
     } 
} 

編輯:我試圖消除兩個非唯一索引(key.a_1key.b_1),看看是否這可能會影響查詢。這不是:

> db.collection.find({"key.a": 456213154}).explain() 
{ 
     "cursor" : "BasicCursor", 
     "nscanned" : 23240518, 
     "nscannedObjects" : 23240518, 
     "n" : 10962, 
     "millis" : 15047, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "isMultiKey" : false, 
     "indexOnly" : false, 
     "indexBounds" : { 

     } 
} 
+0

你可以在兩個查詢上發佈'explain()'運行的輸出嗎? http://www.mongodb.org/display/DOCS/Explain – shelman

+1

根據'explain'輸出,你有10962個文檔,其中''key.a''是456213154,並且他們都沒有'鍵。 b'領域。那是對的嗎? – JohnnyHK

+0

所有'key'子文檔總是有'a'和'b'。沒有任何用例可能會丟失或「空」。 – nilskp

回答

4

explain()輸出提示:

  1. 有10962個對象有key.a : 456213154。您的db.collection.find({"key.a": 456213154})查詢使用key.a上的索引,並返回10962個對象。

  2. 您的收藏中有0個物體具有key.a : 456213154且有key.b : { $exists : true }db.collection.find({"key": {"a": 456213154, "b": {"$exists":true}}})查詢確實在密鑰上使用了您的索引。

查看每個查詢的n值 - 這是返回的數字;和cursor值 - 如果使用索引,則爲BtreeCursor。在這種情況下,爲什麼第一個查詢需要更長時間纔有意義,因爲它有更多的對象要返回。

是否確定具有key.a : 456213154值的文檔也具有key.b值?

編輯:

$exists PARAM的查詢是嵌入文檔中檢查是否存在錯誤的語法。

嘗試db.collection.find({ "key.a" : 456213154, "key.b" : { "$exists" : true } })

+0

你是對的,第二個查詢返回沒有結果。所以'$ exists'部分不匹配任何東西。所以問題是,我將如何寫出匹配的東西?我嘗試了'{「$ ne」:null}'也沒有匹配。 – nilskp

+0

看起來好像您的所有文檔的key.a等於456213154都沒有key.b字段。我對麼?在這種情況下,$存在的部分不應該匹配任何東西。 – shelman

+0

不,就像我之前寫的那樣,總是填充'a'和'b'。我想這就是把我扔掉的原因,因爲我認爲查詢將與書面匹配。 – nilskp