2013-01-18 49 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