2014-02-08 82 views
0

我有一大堆「消息」與'到','從','類型'和'visible_to'字段,我想查詢與一個相當複雜的查詢,只拉扯消息/從一個特定該用戶可見的特定類型的用戶。下面是一個實際的例子:強制使用複雜的MongoDB查詢索引?

{ 
    "$and": [ 
    { 
     "$and": [ 
     { 
      "$or": [ 
      { 
       "to": "52f65f592f1d88ebcb00004f" 
      }, 
      { 
       "from": "52f65f592f1d88ebcb00004f" 
      } 
      ] 
     }, 
     { 
      "$or": [ 
      { 
       "type": "command" 
      }, 
      { 
       "type": "image" 
      } 
      ] 
     } 
     ] 
    }, 
    { 
     "$or": [ 
     { 
      "public": true 
     }, 
     { 
      "visible_to": "52f65f592f1d88ebcb00004f" 
     } 
     ] 
    } 
    ] 
} 

使用索引:

[ 
    { 
     "v" : 1, 
     "key" : { 
      "_id" : 1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "_id_" 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "expires" : 1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "expires_1", 
     "background" : true, 
     "safe" : null 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "from" : 1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "from_1", 
     "background" : true, 
     "safe" : null 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "type" : 1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "type_1", 
     "background" : true, 
     "safe" : null 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "ts" : 1, 
      "type" : -1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "ts_1_type_-1", 
     "background" : true, 
     "safe" : null 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "to" : 1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "to_1", 
     "background" : true, 
     "safe" : null 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "visible_to" : 1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "visible_to_1", 
     "background" : true, 
     "safe" : null 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "public" : 1, 
      "visible_to" : 1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "public_1_visible_to_1" 
    }, 
    { 
     "v" : 1, 
     "key" : { 
      "to" : 1, 
      "from" : 1 
     }, 
     "ns" : "n2-mongodb.messages", 
     "name" : "to_1_from_1" 
    } 
] 

這裏是我們的MongoDB 2.2.2實例講解(真)的輸出,它看起來像一個全掃描:

{ 
    "cursor" : "BasicCursor", 
    "isMultiKey" : false, 
    "n" : 0, 
    "nscannedObjects" : 35702, 
    "nscanned" : 35702, 
    "nscannedObjectsAllPlans" : 35702, 
    "nscannedAllPlans" : 35702, 
    "scanAndOrder" : false, 
    "indexOnly" : false, 
    "nYields" : 1, 
    "nChunkSkips" : 0, 
    "millis" : 85, 
    "indexBounds" : { 

    }, 
    "allPlans" : [ 
     { 
      "cursor" : "BasicCursor", 
      "n" : 0, 
      "nscannedObjects" : 35702, 
      "nscanned" : 35702, 
      "indexBounds" : { 

      } 
     } 
    ], 
    "server" : "XXXXXXXX" 
} 

看看解釋輸出,MongoDB沒有使用任何索引 - 有沒有辦法讓它至少使用複合索引{to:1,from:1}來顯着縮小搜索空間?或者有更好的方法來優化這個查詢嗎?或者是MongoDB完全不適合這樣的查詢?

+1

使用'$或',每個子句都可以使用自己的索引。你可以包含這個查詢的'explain(true)'和這個集合的'db.collection.getIndexes()'的輸出嗎?在你的六個條款中,你建議的{to,from}索引只適用於一個。 – Stennie

+0

@Stennie記住嵌套的$ ors在下一個版本之前不會有優化,他可能使用舊版本 – Sammaye

+0

那麼你是說如果我有一個索引{to:1,from:1}和索引{public:1 ,visible_to:1}和一個索引{type:1},它會在2.4版本之後使用它們中的每一個? – outside2344

回答

0

MongoDB中2.6查詢優化器將包括用於應用索引複雜查詢的支持。

0

要強制MongoDB查詢優化器採用特定方法,可以使用$hint運算符。 從文檔,

The $hint operator forces the query optimizer to use a specific index to fulfill the query.  Specify the index either by the index name or by document.