Mongo中的排序和索引是一個複雜的話題。如果你有太多的項目,Mongo也有一個特殊的錯誤,它會阻止你在沒有索引的情況下進行排序。所以你最好問索引,因爲一個未索引的類最終會失敗。
有一個bug in JIRA似乎涵蓋您的問題,但有一些額外的細節要考慮。
要注意的第一件事情是你最後的疑問:
db.tasks.find({title:/^japan/}).sort({total:-1})
db.tasks.find({keywords:/^japan/}).sort({total:-1})
因爲你是唯一的索引上title
不是title/total
這些查詢最終將失敗。這裏有一個腳本來演示這個問題。
> db.foo.ensureIndex({title:1})
> for(var i = 0; i < 100; i++) { db.foo.insert({title: 'japan', total: i}); }
> db.foo.count()
100
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
... uses BTreeCursor title_1
> // Now try with one million items
> for(var i = 0; i < 1000000; i++) { db.foo.insert({title: 'japan', total: i}); }
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
Sat Mar 31 05:57:41 uncaught exception: error: {
"$err" : "too much data for sort() with no index. add an index or specify a smaller limit",
"code" : 10128
}
所以,如果你打算查詢&排序上title
和total
,那麼你就需要在這兩個指標,按照這個順序:
> db.foo.ensureIndex({title:1,total:1})
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
{
"cursor" : "BtreeCursor title_1_total_1 reverse",
...
我上面列出的JIRA的bug是有點像以下:
> db.foo.find({$or: [title:/^japan/, title:/^korea/]}).sort({total:-1})
此致略有不同,但會遇到同樣的問題。即使您在title/total
和keyword/total
上都有索引,MongoDB也無法以最佳方式使用索引。
如果您有{total:-1,title:1}的索引並按{total:-1,title:1}排序,那麼至少是否使索引掃描更有效? – drogon 2013-02-25 23:08:06
@drogon你在過濾什麼?那裏有一個'find()'子句嗎? JIRA錯誤是非常具體的使用'$或'子句進行排序。 – 2013-02-26 23:13:12