MongoDB 随机查询一条数据语语句

作者:袖梨 2022-06-29

换个思路,我们可以在每个文档加一个随机键(random),用Math.random()方法生成随机数,存放进文档里。查询的时候,同样用Math.random()生成一个随机数,返回一条集合中随机数小于这个随机数的文档。当然,也有可能没有小于这个随机数的文档,但如果这样,就必定有一个大于等于这个随机数的文档,除非集合是空的。

查询一条随机数据

 代码如下 复制代码

var random=Math.random();
var result=db.user.findOne({"random":{"$lt":random}});
if(result==null)
{
result=db.user.findOne({"random":{"$gte":random}});
}

PRIMARY> db.phoneMessage.count()
8704224
PRIMARY> db.phoneMessage.find().limit(-1).skip(Math.floor(Math.random()*8704221)).next()

 
查询多条随机数据

1.参考单条查询,可用个循环,将查询的数据插入到集合t中。

 代码如下 复制代码

for(var i=0;i<1000;i++) {var c=db.phoneMessage.find().limit(-1).skip(Math.floor(Math.random()*8704221)).next(); db.t.insert(c) }

这种方法简单,但是数据量大的情况下,skip效率很低,耗时较长。

2.通过map/reduce来查询

mongodb 2.2以上可用如下方法,2.0格式有点问题

 代码如下 复制代码

function mapf() {
    if(countSubset == 0) return;
    var prob = countSubset / countTotal;
    if(Math.random() <= prob) {
    emit(1, this);
    countSubset--;
    }
    countTotal--;
}

function reducef(key,values) {
    return {"documents": values};
}
res = db.phoneMessage.mapReduce(mapf, reducef, {"out": {"inline": 1}, "scope": {"countTotal": 87042, "countSubset": 1000}})
db.t.insert(res.results[0].value.documents)

此方法也无法应对大数据量情况,会报错InternalError: too much recursion

3.添加一个随机数的字段,再查询就简单了
这种方法会比较好,但更改了集合结构。

相关文章

精彩推荐