2014-08-28 44 views
3

我的意思是,例如,當有兩個條件:如果第一個條件爲真會避免檢查第二個?

doc = collection.find_one(
    {'$or': [ 
       { 
       'k': kind, 
       'i': int(pk) 
       }, 
       { 
       'children.k': kind, 
       'children.i': int(pk) 
       } 

      ] 
    }, { '_id': False}) 

我想在匹配第一個條件時停止進一步搜索,所以它不會在較低層次搜索兒童。

是否在$OR閉合或更確切地說,mongodb知道層次結構,它影響搜索的順序是findOne

回答

2

是的順序很重要,這是一個數組形式的參數當然是有序的強有力的原因。

所以基本上這就是所謂的「短路」評估。所以只有在第一個條件不匹配的情況下才會測試下一個條件等等。

所以最能與這樣一個集展示:

{ "a": 1 }, 
{ "a": 2, "b": 1 } 

,然後將下面的查詢:

db.collection.find({ "$or": [ { "a": 1 }, { "b": 1 } ] }) 

因爲即使先不具備的元素這當然會找到這兩個文件對於「b」,無論如何都滿足了第一個條件。在第一個失敗後的第二個文檔中,第二個文檔用於匹配。

+0

這隻適用於收集掃描案例。正如@sammaye在他的回答中所說的,如果一個索引可以用於兩個子句,那麼兩個'$或'查詢分別執行併合並它們的結果。在這種情況下,條款順序無關緊要。 – JohnnyHK 2014-08-28 12:28:07

2

我想,它停止進一步搜索匹配時的第一個條件,所以它不會降低搜索周圍的兒童。

你一定要問自己的問題是:MongoDB如何知道$or雙方如何滿足一方? MongoDB如何知道不滿足第一個條件的文檔不滿足第二個條件?

如果我說,我有一組文檔,一半{a:1,b:1}和一半{b:2}你怎麼能知道a:1 OR b:1由上半年的滿足,如果你不知道下半年是什麼樣子?

簡單的答案是它沒有。它必須搜索這兩個條件(通過並行查詢,然後返回並重複合並),因爲這樣的順序並不重要,除非它是$and,在這種情況下,順序的重要性在於索引而不是查詢,因爲查詢將是四處移動以優化最快的結果路徑。

所以實際上,MongoDB的工作方式是它爲每個條件發射一個「查詢」。這實際上說明了其行爲:http://docs.mongodb.org/manual/reference/operator/query/or/#behaviors

當使用$或疑問,一個$的每個條款索引或可以使用自己的索引。