lx86 发表于 2015-7-8 08:28:43

MongodB下,从集合中随机选取文档的实现

MongoDB自问世以来,以其简单易用、丰富的文档支持等特点在众多的NoSQL产品中脱颖而出。经过这几年的发展,MongoDB已从原来的小范围的试用,到部署到生产环境中的应用,MongoDB的应用得到了长足的发展,近两年已呈井喷之势。随着MongoDB应用的深入,各种需求也风生水起。笔者在实际的使用MongoDB的过程中,就遇到了从一个集合中随机选取文档的问题。本文就针对该问题提供几种解决方案,并对它们进行分析对比,并通过这种对比使我们对MongoDB做更深入的理解。
一、问题
      在笔者最近参与的一个在线考试项目中,我们采用了MongoDB取代关系数据库作为项目的数据存储系统。我们将所有试题形成一个集合存储在Questions集中,每一试题成为Questions的一个个文档来存储。在为生成考生试卷时,需要从满足一定条件试题集中随机选取几道试题来作为某一考生的考试试题。在以前我们采用Sql Server关系数据库时,对于类似于这种随机获取数据的功能通过一个简单的SQL语句就能完成:

Select Top 5 * From Questions Order By NewID()  通过该语句就可以随机得到5条试题的信息。
而在MongoDB中却没有类似功能可以利用,于是我们只能换其它的思路来解决该问题。
二、解决方案
      在MongoDB中要解决从一个集合中随机获取数据的功能,一般有三种解决方法。其一,保存随机数查询法。在文档插入时给每个文档添加一个额外的随机数,在每次获取时指定一个新的随机数randValue作为查询条件与存储的随机数进行比较,从而得到一组随机的试题。其二,$where查询法。文档本身可以不存在随机数,在查询时事先生成一个随机数randValue,查询采用$where子句,在$where子句的函数中为集合每个文档生成随机数,并与randValue进行比较。其三,将试题的随机选取的任务交由其它语言来完成。比如,通过MongoDb的Java驱动程序来得到集合,然后在Java中对集合中的试题随机选取。
      由于第三种方法中需要将集合传送到本地,然后再从中随机选取,在性能上是这三者中是最差的,并且在数据较大的情况下,也容易出现内存泄漏等诸多的问题,所以本文将舍弃该方法,不做详细的讨论。其它的二个方法都有各自的优势,适用于不同的情况下。
1)保存随机数查询法
我们在mongo中采用JavaScript插入100万个模拟的试题文档



for(var i=0;i
页: [1]
查看完整版本: MongodB下,从集合中随机选取文档的实现