• 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”集合里面按键分组的情况。

  • 相关阅读:
    Win7下通过eclipse远程连接CDH集群来执行相应的程序以及错误说明
    Java中的Scanner类和String类
    java的eclipse操作和常用类Object的使用
    如何利用Cloudera Manager来手动安装parcel包
    java.io.IOException: Too many open files
    java中的包以及内部类的介绍
    HDFS中的checkpoint( 检查点 )的问题
    HDFS中Java的API使用测试
    利用ClouderaManager启动HBase时,出现 master.TableNamespaceManager: Namespace table not found. Creating...
    MapReducer程序调试技巧
  • 原文地址:https://www.cnblogs.com/lucyawei/p/3047594.html
Copyright © 2020-2023  润新知