2013-01-18 44 views
1

在我的數據庫我有一個集合,其中文檔有一個字段score,它是一個浮點數(-1..1)。我可以查詢數據庫返回按分數排序的前20個結果。MongoDB:按計算屬性排序

我的問題是,我想根據字段time_updated修改文檔的時間處罰分數:文檔越老,分數應該越低。最大的問題是,我必須在運行時執行此操作。我可以迭代所有文檔,更新分數,然後按分數排序。但是這會花費太多時間,因爲集合中有大量文檔。

所以我的問題是:有了MongoDB,我可以通過計算屬性來訂購嗎?有沒有辦法做到這一點?或者是否有計劃下一版MongoDB的功能?

+1

在聚合框架中,它是否能以足夠的性能在您的方案中使用(我假設在頁面上進行特殊查詢),取決於您計算的行數,計算的字段,就像在SQL中一樣,必須在內存中進行排序。 – Sammaye

+0

你對聚合框架有什麼意義? Rails或者像這樣?每個用戶可以有大約10.000行,我只想檢索前20位。所以現在我必須獲取10.000行,計算新的基於時間的分數,按分數排序並返回僅20行。我認爲這是一點點的開銷。我在Rails 3中做了這些,我認爲這不是最快的方法。 – 23tux

+2

這是一個聚合框架:http://docs.mongodb.org/manual/applications/aggregation/它是在2.1中引入的,它很像SQL,它擁有很多在標準SQL聚合框架中找到的功能。 – Sammaye

回答

2

分數究竟如何更新?

如果它很簡單並且可以放入$add, $multiply, etc., terms那麼聚合管道就可以正常工作。否則,您需要使用簡單的MapReduce a來完成分數更新。

var mapFunction = function() { 
    emit(this._id, <compute score here from this.score and this.time_updated>); 
}; 

var reduceFunction = function (values) { 
    return values[0]; // trivial reduce function since incoming id's are unique. 
}; 

對於10000行,聚合管道或簡單的MapReduce可能會有足夠的性能。

對於更大的數據集,您可能需要使用更復雜的MapReduce(實際上是減少)以提高內存效率。您可能還想利用Incremental MapReduce