Mongodb 学习笔记4:游标、聚合

游标

用var声明一个变量,用于保存查询的结果。

var cursor=db.users.find();

上述语句之后,cursor其实并没有获取到users中的文档,而是申明一个“查询结构”,等我们需要的时候通过

for或者next()一次性加载过来,然后让游标逐行读取,当我们枚举完了之后,

游标销毁,之后我们在通过curs获取时,

发现没有数据返回了。

通过curso.hasNext()检查是否有后续结果存在,然后用cursor.next() 将其获得。

"查询构造":

db.users.find().limit(3):返回三个匹配的文档。

db.users.find().skip(3):略过前三个匹配的文档,然后返回其他。

db.users.find().sort("name",1):按name升序返回结果,-1降序。

注意:避免使用skip()略过大量的结果。其处理速度很慢。

不用skip对结果分页:

以"date"降序显示文档,获取结果的第一页:

var page1=db.users.find().sort({"date":-1}).limit(100)

可以利用最后一个文档中"date“的值作为查询条件,来获取下一页:

var lastest=null;

//display first page

while(page1.hasNext()){

latest=page1.next();

display(latest);

}

//get next page

var page2=db.users.find({"date":{"$gt":latest.date}});

page2.sort({"date":-1}).limit(100);

随机选取文档

>//do not use

>var total=db.users.count()

> var random=Math.floor(Math.random()*total)

>db.foo.find().skip(random).limit(1)

这种方法效率很低,不可取。

可以在插入文档的时候,添加一个额外的随机键"andom“:Math.random()

> var random=Math.random()

>result=db.users.findOne({"random":{"$gt":random}})

>if(result==null){

... result=db.users.findOne({"random":{"$lt":random}})

...} 

 高级查询选项:

  • $maxscan:integer  指定查询最多扫描的文档数量
  • $min:document  查询开始的条件
  • $max:document 查询结束的条件
  • $hint:document 指定服务器使用哪个索引进行查询
  • $explain:boolean 获取查询执行的细节(用到的索引、结果数量、耗时等),而非真正执行查询。
  • $snapshot:boolean 确保查询结果是在查询执行那一刻的一致快照。

 聚合

count:返回集合中文档的数目

distinct:找出给定键的所有不同值。

group:

参数介绍:

       key:  这个就是分组的key,我们这里是对年龄分组。

       initial: 每组都分享一个”初始化函数“,特别注意:是每一组,比如这个的age=20的value的list分享一个

initial函数,age=22同样也分享一个initial函数。

       $reduce: 这个函数的第一个参数是当前的文档对象,第二个参数是上一次function操作的累计对象,第一次

为initial中的{”perosn“:[]}。有多少个文档, $reduce就会调用多少次。

 下面举的例子就是按照age进行group操作,value为对应age的姓名。

 

condition 过滤条件

 finalize:这是个函数,每一组文档执行完后,都会触发此方法,那么在每组集合里面加上count也就是它的活了。

 MapReduce:

     count 、distinct、group 能做的事情基本上都能做。可以轻松并行化到多个服务器的聚合方法。它会拆分问题,再将各个部分发送到不同的机器上,让每台机器都完成一部分。所有机器完成的时候,在把结果汇集起来。使用MapReduce的代价就是速度,绝不要用在“实时”的环境中。作为后台任务来运行。

步骤:

  • 映射(map):将操作映射到每个文档。操作要么是”无作为“,要么产生一些键值和X个值。里面会调用emit(key,value),集合会按照你指定的key进行映射分组。
  • 洗牌(shuffle):按照键值分组,并将产生的键值组成列表放到对应的建中。
  • 化简(reduce):则把列表中的值化简为一个单值,并返回。然后接着洗牌,知道每个键的列表只有一个值为止。

    注意:在reduce(key,value)中的key就是emit中的key,vlaue为emit分组后的emit(value)的集合,这里也就是很多{"count":1}的数组。

  • mapReduce:这个就是最后执行的函数了,参数为map,reduce和一些可选参数。

以下程序是找出集合中的所有键:

this 是当前映射文档的引用;map函数使用"emit"返回要处理的值。文档为每一个键值调用一次emit。

那样就会返回:{count:1,id:1}、{count:1,id:2}、{count:1,id:3},其中id键用于区别。然后将这两个返回值传给reduce函数。

从图中我们可以看到如下信息:

       result: "存放结果的集合名“;

       input:传入文档的个数。

       emit:此函数被调用的次数。

       reduce:此函数被调用的次数。

       output:最后返回文档的个数。

最后我们看一下“collecton”集合里面按键分组的情况。

原文地址:https://www.cnblogs.com/lucyawei/p/3047594.html