2012-03-31 30 views
0

它看起來像使用$或與排序做一個完整的表掃描,並避免我的標題和關鍵字索引我怎麼能得到它使用我的兩個索引時使用$或查詢?

這個查詢使用標題和關鍵字索引

db.tasks.find({$or: [{keywords: /^japan/}, {title:/^japan/}]}) 

這個執行全表掃描,並使用我的索引total_-1

db.tasks.find({$or: [{keywords: /^japan/}, {title:/^japan/}]}).sort({total:-1}) 

而針對關鍵字或標題查詢帶有幾分做分別使用關鍵字或標題上的索引。

db.tasks.find({title:/^japan/}).sort({total:-1}) 
db.tasks.find({keywords:/^japan/}).sort({total:-1}) 

回答

1

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 
} 

所以,如果你打算查詢&排序上titletotal,那麼你就需要在這兩個指標,按照這個順序:

> 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/totalkeyword/total上都有索引,MongoDB也無法以最佳方式使用索引。

+0

如果您有{total:-1,title:1}的索引並按{total:-1,title:1}排序,那麼至少是否使索引掃描更有效? – drogon 2013-02-25 23:08:06

+0

@drogon你在過濾什麼?那裏有一個'find()'子句嗎? JIRA錯誤是非常具體的使用'$或'子句進行排序。 – 2013-02-26 23:13:12

相關問題