MongoDB动态排名

时间:2013-07-28 21:39:17

标签: performance mongodb ranking

我使用MongoDB并拥有一个包含大约100000个条目的集合。

条目包含如下数据:

{"page": "page1", "user_count": 1400}
{"page": "page2", "user_count": 1100}
{"page": "page3", "user_count": 900}
...

我想根据user_count输出条目的排名,如:

#1 - page1
#2 - page2
#3 - page3
...

......到目前为止一切顺利。如果我只输出一个排序列表,我可以简单地使用一个循环计数器。 :)

但我还必须支持各种搜索查询。因此,例如,我得到20个结果,并希望显示结果的排名。像:

#432 - page1232
#32  - page223
#345 - page332
...

最好的方法是什么?因为收藏不断变化,我不想将排名存储在集合中。我尝试使用我在飞行中构建的查找字典来解决它,但它确实很慢。 MongoDB是否有任何特殊功能可以帮助这些案例?

2 个答案:

答案 0 :(得分:3)

没有一个命令可以用来执行此操作,但您可以使用count来执行此操作:

var doc = db.pages.findOne(); // Or however you get your document
var n = db.pages.find({user_count : {$gt : doc.user_count}}).count(); // This is the number of documents with a higher user_count
var ranking = n+1; // Your doc is next in a ranking

单独的qustion是你应该这样做。请考虑以下事项:

  • 您需要有关user_count的索引。你可能已经有了这个。
  • 您需要为正在显示的每条记录执行计数查询。没有办法批量处理这些。

鉴于此,除了根据应用程序的CRUD配置文件将排名存储在集合中之外,您可能会对性能产生更大的影响 - 由您决定什么是最佳选择。

答案 1 :(得分:1)

使用 MongoDB 解决此问题没有简单的方法。 如果有可能,我会建议您查看 Redis 及其Sorted Sets。正如文件所说:

  

使用分类集,您可以:在大型在线游戏中使用排行榜,每次提交新分数时,您都可以使用ZADD进行更新。您可以使用ZRANGE轻松吸引热门用户,您还可以使用ZRANK在给定用户名的情况下在列表中返回其排名。同时使用ZRANKZRANGE可以向用户显示与给定用户类似的分数。一切都很快。

您可以使用MULTI/EXEC块轻松获取随机页面的排名。所以这是我认为你的任务的最佳方法,它比使用MapReduce或重新使用mongodb要快得多。