zoukankan      html  css  js  c++  java
  • MongoDB中的分组

    .MongoDB中的Count函数、Distinct函数以及分组

     准备工作,插入一个班级的文档

    > for(var i=0;i<10;i++){

    ... db.Classes.insert({ClassName:"Class"+i,_id:i});

    ... }

    WriteResult({ "nInserted" : 1 })

    > db.Classes.find()

    { "_id" : 0, "ClassName" : "Class0" }

    { "_id" : 1, "ClassName" : "Class1" }

    { "_id" : 2, "ClassName" : "Class2" }

    { "_id" : 3, "ClassName" : "Class3" }

    { "_id" : 4, "ClassName" : "Class4" }

    { "_id" : 5, "ClassName" : "Class5" }

    { "_id" : 6, "ClassName" : "Class6" }

    { "_id" : 7, "ClassName" : "Class7" }

    { "_id" : 8, "ClassName" : "Class8" }

    { "_id" : 9, "ClassName" : "Class9" }

    >

     

    1.count函数

    如上面,如果要统计班级的数目,可以使用count函数进行统计

    > db.Classes.find().count()

    10

    >

     

    2.Distinct函数

    修改一下Classes文档,添加一条重复的数据

    > db.Classes.insert({_id:10,ClassName:"Class9"})

    WriteResult({ "nInserted" : 1 })

    > db.Classes.find()

    { "_id" : 0, "ClassName" : "Class0" }

    { "_id" : 1, "ClassName" : "Class1" }

    { "_id" : 2, "ClassName" : "Class2" }

    { "_id" : 3, "ClassName" : "Class3" }

    { "_id" : 4, "ClassName" : "Class4" }

    { "_id" : 5, "ClassName" : "Class5" }

    { "_id" : 6, "ClassName" : "Class6" }

    { "_id" : 7, "ClassName" : "Class7" }

    { "_id" : 8, "ClassName" : "Class8" }

    { "_id" : 9, "ClassName" : "Class9" }

    { "_id" : 10, "ClassName" : "Class9" }

     

    现在我想查询所有ClassName,去掉重复的,可以执行下面的操作。

    > db.runCommand({distinct:"Classes",key:"ClassName"}).values

    [

            "Class0",

            "Class1",

            "Class2",

            "Class3",

            "Class4",

            "Class5",

            "Class6",

            "Class7",

            "Class8",

            "Class9"

    ]

    >

    去重语法 db.runCommand({distinct:"数据集合名字",key:"需要去重的键"}).values

     

    3.Group分组操作(比较复杂)

    语法:

    db.runCommand({group:{

            ns:集合名字,

     Key:分组的键对象,

     Initial:初始化累加器,

     $reduce:组分解器,

     Condition:条件,

     Finalize:组完成器

          }})

     

     1).key:用来分组文档的字段。和keyf两者必须有一个

     2).keyf:可以接受一个javascript函数。用来动态的确定分组文档的字段。和key两者必须有一个

     3).initial:reduce中使用变量的初始化

     4).reduce:执行的reduce函数。函数需要返回值。

     5).cond:执行过滤的条件。

     6).finallize:在reduce执行完成,结果集返回之前对结果集最终执行的函数。可选的。

     

    具体的使用可以参考手册:http://mongodb-documentation.readthedocs.org/en/latest/reference/command/group.html

    分组首先会按照key进行分组,每组的 每一个文档全要执行$reduce的方法,他接收2个参数一个是组内本条记录,一个是累加器数据.

     

    新建一个persons集合,插入一下数据

    var persons = [{

    name:"Tom",

    age:25,

    country:"USA"

    },

    {

    name:"Jack",

    age:25,

    country:"USA"

    },

    {

    name:"Lucy",

    age:26,

    country:"USA"

    },

    {

    name:"DaChengzi",

    age:27,

    country:"China"

    },

    {

    name:"Xiaojuz",

    age:26,

    country:"China"

    },

    {

    name:"DaPingguo",

    age:27,

    country:"China"

    },

    {

    name:"XiaoBoluo",

    age:27,

    country:"China"

    },

    {

    name:"Bangzi1",

    age:26,

    country:"Korea"

    },

    {

    name:"LiShishi",

    age:27,

    country:"Korea"

    },

    {

    name:"Rain",

    age:21,

    country:"Korea"

    },

    {

    name:"CangJingkong",

    age:30,

    country:"Japan"

    }]

    for(var i = 0;i<persons.length;i++){

    db.persons.insert(persons[i])

    }

    插入完成后,查看一下:

     

    现在我有一个需求,想要找到每个国家当中年纪最大的人,并且年纪不大于30岁,输出他们的名字

     

    思路: ①先按照国家进行分组

             ②找到每个国家中年纪最小的

             ③判断年纪是不是小于30

     

    编写查询:

    db.runCommand({group:{

    ns:"persons",

    key:{"country":true},

    initial:{age:0},

    $reduce:function(doc,prev){

    if(doc.age>prev.age){

    prev.age=doc.age;

    prev.name = doc.name;

    prev.country = doc.country;

    }

    },

    condition:{age:{$lt:30}}

    }})

     

    运行结果:

    {

            "retval" : [

             {

                  "country" : "USA",

                   "age" : 26,

                            "name" : "Lucy"

                    },

                    {

                            "country" : "China",

                            "age" : 27,

                            "name" : "DaChengzi"

                    },

                    {

                            "country" : "Korea",

                            "age" : 27,

                            "name" : "LiShishi"

                    }

            ],

            "count" : 10,

            "keys" : 3,

            "ok" : 1

    }

     

    从结果看到日本女士苍井空的年龄是30,被我筛选掉了…...

     

    Finallize的使用,如果觉得返回的东西太过单调,可以使用finalize进行再次的修改

     

    例如:

    db.runCommand({group:{

    ns:"persons",

    key:{"country":true},

    initial:{age:0},

    $reduce:function(doc,prev){

    if(doc.age>prev.age){

    prev.age=doc.age;

    prev.name = doc.name;

    prev.country = doc.country;

    }

    },

    finalize:function(prev){

    prev.age = "Age is" +prev.age;

    prev.name = "Name is " + prev.name;

    prev.country = "Country is " + prev.country;

    },

    condition:{age:{$lt:30}}

    }})

     

    加上上面之后,查询的结果如下:

    {

            "retval" : [

                    {

                            "country" : "Country is USA",

                            "age" : "Age is26",

                            "name" : "Name is Lucy"

                    },

                    {

                            "country" : "Country is China",

                            "age" : "Age is27",

                            "name" : "Name is DaChengzi"

                    },

                    {

                            "country" : "Country is Korea",

                            "age" : "Age is27",

                            "name" : "Name is LiShishi"

                    }

            ],

            "count" : 10,

            "keys" : 3,

            "ok" : 1

    }

    可以看到每一项数据前面,都加上了说明文字,所以说finialize是可以对分完组之后的数据在做一次修改的。

     

    .命令执行器(db.runCommand())

    1.之前我们遇到删除集合,一般使用的方法是 db.集合名.drop()

    使用命令执行器:

    db.runCommand({drop:"集合"})

     

    2.查找MongoDB为我们提供的命令

    ①在shell中执行:db.listCommands()

    ②访问网址http://127.0.0.1:28017/_commands

     

    3.常用命令

    .固定集合(Capped Collection

    1.解释:就是固定size的集合呗。

    2.特点:性能出色的有着固定大小的集合,以LRU(Least Recently Used最近最少使用)规则和插入顺序进行age-out(老化移出)处理,自动维护集合中对象的插入顺序,在创建时需要预先指定大小。如果空间用完,新添加的对象将会取代集合中最旧的对象永远保持最新的数据

    总结就是以下:

    ①固定集合默认是没有索引的就算是_id也是没有索引的

    ②由于不需分配新的空间他的插入速度是非常快的

    ③固定集合的顺是确定的导致查询速度是非常快的

    ④最适合的是应用就是日志管理

    3.使用

    ①创建一个固定集合

      创建一个新的固定集合要求大小是100个字节,可以存储文档10

     > db.createCollection("myCapped",{size:100,capped:true,max:10})

        { "ok" : 1 }

     >

     

    ②把一个普通集合转成固定集合

    > db.runCommand({convertToCapped:"Classes",size:100000})

    { "ok" : 1 }

    >

     

    ③插入数据

    文档最大为10个,那么当插入11条数据的时候,会出现什么情况呢,根据之前的概念,应该是吧第一条数据踢出去,然后加入最后一条

    > for(var i = 0; i<11;i++){

    ... db.myCapped.insert({name:"name"+i,_id:i})

    ... }

    WriteResult({ "nInserted" : 1 })

    > db.myCapped.find()

    { "_id" : 1, "name" : "name1" }

    { "_id" : 2, "name" : "name2" }

    { "_id" : 3, "name" : "name3" }

    { "_id" : 4, "name" : "name4" }

    { "_id" : 5, "name" : "name5" }

    { "_id" : 6, "name" : "name6" }

    { "_id" : 7, "name" : "name7" }

    { "_id" : 8, "name" : "name8" }

    { "_id" : 9, "name" : "name9" }

    { "_id" : 10, "name" : "name10" }

    >

    > db.myCapped.insert({name:"name11",_id:11})

    WriteResult({ "nInserted" : 1 })

    > db.myCapped.find()

    { "_id" : 2, "name" : "name2" }

    { "_id" : 3, "name" : "name3" }

    { "_id" : 4, "name" : "name4" }

    { "_id" : 5, "name" : "name5" }

    { "_id" : 6, "name" : "name6" }

    { "_id" : 7, "name" : "name7" }

    { "_id" : 8, "name" : "name8" }

    { "_id" : 9, "name" : "name9" }

    { "_id" : 10, "name" : "name10" }

    { "_id" : 11, "name" : "name11" }

    >

    ④删除数据

    > db.myCapped.remove({_id:11})

    WriteResult({

            "nRemoved" : 0,

            "writeError" : {

                    "code" : 10101,

                    "errmsg" : "cannot remove from a capped collection: mongoDBTest.myCapped"

            }

    })

    >

    如上例,固定集合是不能进行数据删除的。

    综上:固定集合有点像一个队列,先进先出,大小不变。

     

     

     

     

     

     

     

     

  • 相关阅读:
    android29
    android28
    android27
    android26
    Dynamics CRM2011 MspInstallAction failed when installing an Update Rollup
    Dynamics CRM Import Solution Attribute Display Name description is null or empty
    The service cannot be activated because it does not support ASP.NET compatibility
    IIS部署WCF报 无法读取配置节“protocolMapping”,因为它缺少节声明
    Unable to access the IIS metabase.You do not have sufficient privilege
    LM算法与非线性最小二乘问题
  • 原文地址:https://www.cnblogs.com/dcz2015/p/5314273.html
Copyright © 2011-2022 走看看