2014-02-06 32 views
0

,如果我有這些文檔:MongoDB的索引範圍發現

{"name": 1, "score": 2} 
{"name": 1, "score": 4} 
{"name": 2, "score": 2} 
{"name": 2, "score": 4} 

如果我保證指數:

db.test.ensureIndex({"name":1, "score":1}) 

然後我試圖找到():

db.test.find({"score": 4}) 

我用explain(),並發現這個查詢不能使用索引,它會掃描所有的四個文檔。

我不知道爲什麼它會掃描所有的文檔?

你知道,如果我枚舉所有的「名」的值(1和2):

db.test.find({"$or":["name":1, "name":2], "score":4}) 

它可以使用索引,只掃描的兩個文檔。

爲什麼mongodb無法爲我做這件事?

+1

你不應該使用$或當兩個子句有相同的字段。改用{name:{$ in:[1,2]}}。 –

回答

1

不使用索引的原因是因爲$or排除運營商,這意味着,以確定什麼是比賽或多或少掃描的一切。

你真正想使用的是$in。這將減少匹配到只有包含在該集合中的那些值。

db.test.find({"$in":["name":1, "name":2], "score":4}) 

由於這是包容那場比賽可以被應用於索引沒有做一個完整的掃描。

0

一般的經驗法則是:如果你有一個綜合指數,你通過一個字段從它可以搜索,你還必須指定所有字段到它在索引定義左邊。

你能想到的綜合指數的這種方式:文檔被索引/由第一場分組,然後,這些羣體中,他們是由第二場索引。

所以,當你試圖通過第二場進行搜索,不指定第一個,蒙戈將要掃描整個索引,因爲它不能有效地從穿越排除項目。

db.test.find({"name": {"$in": [1, 2]}, "score": 4}) 

在這種情況下,它只會查看name = 1和name = 2索引條目並在那裏查找score = 4。如果您不指定名稱,它將掃描所有內容。這不是非常有效。

0

在MongoDB中,如果有關於收集一個複合索引(如您的收藏中的情況下,複合索引是(姓名,分數)),索引字段的順序是非常重要的。 MongoDB只能將複合索引用於包含索引字段前綴的查詢。所以,在你的情況下,索引將只針對查詢,其中包括:
1)姓名字段
2)姓名和分數字段。

對於任何其他查詢,索引將不會被使用。這是因爲mongoDB創建複合索引的方式。文件將首先通過名稱字段索引,然後通過分數字段索引。如果查詢僅包含分數字段,那麼mongoDB無法使用索引來查找文檔。

參考:http://docs.mongodb.org/manual/core/index-compound/#compound-index-prefix