2013-08-01 23 views
1

我有一個存儲有關文章信息的集合。該集合用於存檔目的,因此它是隻讀的。目前只有兩個字段正在使用:「title」和「page_length」。因爲我總是希望首先獲取較長的文章,所以我有以下索引:{title:1,page_length:-1}。是否可以物理地重組mongoDB集合以避免使用sort()?

我發現這種排序仍然很慢,因爲集合非常大,不適合內存。

假設幾乎查詢我使用這個集合將需要排序({page_length:-1}),有什麼辦法簡單地按照page_length降序存儲在磁盤上的記錄?換句話說,是否有一種簡單的方法可以使集合中的第一條記錄成爲最大的page_length值,第二條記錄是第二大的記錄等等?

這樣我就可以使用limit(n)獲取前n條記錄,而無需運行排序。有任何想法嗎?


更多信息的更新:

我用這一個搜索自動完成功能,這樣的速度是至關重要的。我一直在使用看起來像這樣的查詢:我很高興能創建多個索引,因爲插入不關心

db.articles.find({"title": /^SomeKeyword/}).sort({page_length:-1})

,我只是想最大限度地提高讀取速度。

編輯:作爲參考,我實際上能夠通過使用find()。forEach()將新集合中的記錄重新組織起來。然後我搜索了這個集合,並且獲得了前N個結果,而不需要任何排序,這非常有效。請注意,這隻適用於我的數據集不會改變。

回答

0

我可以想到使用兩個查詢的解決方案。

首先,您可以執行covered query以獲取您關心的文檔列表。其次,您可以使用檢索到的文檔列表和$in運算符來獲得最終結果。

被覆蓋的查詢將在內存中運行(或至少在磁盤上依次運行),所以它應該很快,並且$in可以利用_id索引,並且對於合理數量的文檔應該是有效的。

+0

你能給我舉例說明我怎麼能做到這一點? – soulkphp

1

您的索引{ title: 1, page_length: -1 }不用於查詢,看起來像這樣:

db.collection.find({}).sort({ page_length: -1 }); 

MongoDB中只能使用複合索引由左到右,所以爲了要使用的索引,則需要將「title」作爲查找或排序參數:

db.collection.find({title:'foo'}).sort({page_length:-1}); db.collection.find()。sort({title:1,page_length:-1});

說明會告訴你:

db.so.find({}).sort({ page_length: -1 }).explain(); 

{ 
    "cursor" : "BasicCursor", 
    … 

如果您更改索引:

db.so.ensureIndex({ page_length: -1, title: 1 }); 

那麼該指數將用於排序,但你不能用指數只是做一個由title查找,你需要一個額外的索引。如果你真的只對這兩個領域感興趣,並確保你使用覆蓋索引有幫助。您將必須具有{ page_length: -1, title: 1 }的複合索引,並且可以確保它通過使用投影來使用:

db.collection.find({},{page_length:1,title:1,_id:0}) .sort({page_length:-1});

但是你不能決定或影響MongoDB如何在磁盤上存儲東西。

+0

謝謝!我在這個問題中增加了更多細節。你認爲我應該爲這個標題和一個複合索引創建一個索引嗎? – soulkphp

+0

另外,爲了捕捉我的索引不真正工作的事實+1。 – soulkphp

相關問題