zoukankan      html  css  js  c++  java
  • MongoDB 4.0.10 聚合

    • db.<collection>.group(document):首先根据cond查询条件筛选符合条件的数据,然后按照key分组属性把数据分成不同组,每一组都经过initial进行变量初始化,在经过reduce函数进行计算,其中curr参数代表该组的一个文档,result参数在最后的时候返回,统计完该组之后调用finalize函数
    • group方法的不足之处:需要手写聚合函数的业务逻辑,且不支持分片计算,无法分布式计算
    • 示例在SQL_DB中Learn09.js
     1 db.<collection>.group(document)
     2 // document指定是
     3 {
     4     key:{key1:1, key2:1},                  // 分组属性
     5     keyf:{ },                              // 可选,用于代替参数key,可以不指定其属性为分组字段的对象,而是指定一个函数,该函数返回一个用于分组的key对象
     6     cond:{ },                              // 可选,查询条件
     7     reduce:function(curr, result){ },      // 每一组数据执行的聚合函数,curr代表该组的一个文档,result代表该组的一个聚合结果
     8     initial:{},                            // 进入每组之前进行变量参数初始化
     9     finalize:function(){ }                 // 可选,统计完一组后的回调函数
    10 }
    • db.<collection>.aggregate(AGGREGATE_OPERATION),V2.2加入:这是MongoDB的聚合管道,将MongoDB文档在一个管道处理完毕之后将结果传递给下一个管道处理,管道操作是可以重复的
    • 示例在SQL_DB中Learn10.js
     1 $project //select 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档
     2 $match   //where/having 用于过滤数据,只输出符合条件的文档;$match使用MongoDB的标准查询操作
     3 $limit   //limit 用来限制MongoDB聚合管道返回的文档数
     4 $skip    // 在聚合管道中跳过指定数量的文档,并返回余下的文档
     5 $unwind  // 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
     6 $group   //group by 将集合中的文档分组,可用于统计结果
     7 $sort    //order by 将输入文档排序后输出
     8 $geoNear // 输出接近某一地理位置的有序文档
     9 
    10 db.<collection>.aggregate(AGGREGATE_OPERATION)
    11 //示例
    12 // SELECT column_name,COUNT(column_name) AS total FROM kr GROUP BY column_name
    13 db.kr.aggregate([
    14     {$group:{_id:"$column_name",total:{$sum:1}}}
    15 ])
    16 // 按照column_name和article_id进行聚合
    17 db.kr.aggregate([
    18     {$group : {_id : {key1:"$column_name", key2:"$article_id"}, num_total : {$sum : 1}}}
    19 ])
    20 db.runoob.aggregate([{$project:{title:1,url:1,_id:0}}])            // 显示title、url字段
    21 db.runoob.aggregate([{$match:{likes:{$gt:100,$lte:1500}}}])        // 筛选100<likes<=1500的文档
    22 db.runoob.aggregate([{$skip:10}])                                  // 跳过前10个文档
    23 db.runoob.aggregate([{$limit:3}])                                  // 显示前三个文档
    24 db.runoob.aggregate([{$unwind:"$tags"}])                           // tags字段是数组类型,将其进行拆分
    25 db.runoob.aggregate([{$sort:{likes:1}}])                           // 按likes字段升序排列,1代表升序,-1代表降序
    • aggregate()方法中$group中的修饰符
    1 $sum        // sum()/count() 对设置的属性按分组计算总和,如果不是数值类型,则结果为0,设置为1,则为count(*)计数统计
    2 $avg        // 对设置的属性按分组计算平均值,如果不是数值类型,则返回null
    3 $min        // 获取集合中所有文档对应值得最小值, 分组取最小
    4 $max        // 获取集合中所有文档对应值得最大值, 分组取最大
    5 $push       // 在结果文档中插入值到一个数组中,将聚合之后的结果形成一个数组,如果按某个属性聚合之后,对A属性进行push,这把分组中所有的A属性放在一个数组里面
    6 $addToSet   // 在结果文档中插入值到一个数组中,但不创建副本
    7 $first      // 根据资源文档的排序获取每个分组第一个文档数据
    8 $last       // 根据资源文档的排序获取每个分组最后一个文档数据
    • mapReduce(),V2.4加入
      • 关系数据的group不支持分布式运算,而且在单台服务器的运算能力必然是有限的,而mapReduce支持分布式运算,可以在大量的服务器上同时工作,以空间换结果
      • map函数首先按照分组的属性进行分组,将同属于一个组的数据映射到一个数组上去,reduce函数则是将分好的数组进行计算
      • 大坑:分组数据如果大于100,那么它每次取完100条,归并为1条,又返回给map函数作为输入,判断是否余数是否大于100,大于100,取100条,周而复始,直到最后一次取数不大于100,运算完成后就结束
      • 坑:使用Group或MapReduce时,如果一个分类只有一个元素,那么Reduce函数将不会执行,但Finalize函数还是会执行的;这时要在Finalize函数中考虑一个元素与多个元素返回结果的一致性
      • 示例在SQL_DB中Learn11.js、Learn12.js
     1 db.<collecton>.mapReduce(
     2     function(){    emit(key, value);},                // map函数,映射函数,key为统计的键,可以自定义;value为需要添加到数组的值的属性,可以多个
     3     function(key, values){ return reduceFunction },        // reduce统计函数,key为统计的键;values为数组
     4     {
     5         out: <collection>,        // 统计结果放在集合中,如果不指定out:{inline:1}则使用临时集合,在客户端断开后自动删除
     6         query: <document>,        // 筛选条件,只有符合条件的数据才会发到map函数
     7         sort: <document>,         // 排序后发给map函数
     8         limit: <number>,          // 发给map函数的数据数量                
     9         finalize: <function>,     // 在reduce函数执行完后执行,将键和文档作为参数,返回修改的文档
    10         scope: <document>,        // 指定map、reduce、finalize的全局变量
    11         jsMode: <boolean>,        // 指定是否在执行map和reduce函数直接将中间数据转换为BSON格式,默认为false,将map发出的js对象转换为BSON对象,调用reduce将BSON对象转换为js对象
    12         verbose: <boolean>,       // 指定是否包含timing信息,默认为false,不包含
    13         bypassDocumentValidation: <boolean>        // 是否允许mapReduce在操作期间绕过文档验证,这使得可以插入不符合验证要求的文档
    14     }
    15 )
    • aggregate():聚合表达式中使用的字符串运算符和算术运算符
     1 $add           // 计算数值的总和。例如:valuePlus5:{$add:["$value",5]}
     2 $divide        // 给定两个数值,用第一个数除以第二个数。例如:valueDividedBy5:{$divide:["$value",5]}
     3 $mod           // 取模。例如:{$mod:["$value",5]}
     4 $multiply      // 计算数值数组的乘积。例如:{$multiply:["$value",5]}
     5 $subtract      // 给定两个数值,用第一个数减去第二个数。例如:{$subtract:["$value",5]}
     6 $concat        // 连接两个字符串 例如:{$concat:["str1","str2"]}
     7 $strcasecmp    // 比较两个字符串并返回一个整数来反应比较结果。例如 {$strcasecmp:["$value","$value"]}
     8 $substr        // 返回字符串的一部分。例如:hasTest:{$substr:["$value","test"]}
     9 $toLower       // 将字符串转化为小写
    10 $toUpper       // 将字符串转化为大写
    • aggregate():时间关键字
     1 $dayOfYear         // 返回该日期是这一年的第几天 (全年 366 天)
     2 $dayOfMonth        // 返回该日期是这一个月的第几天 (1到31)
     3 $dayOfWeek         // 返回的是这个周的星期几 (1:星期日,7:星期六)
     4 $year              // 返回该日期的年份部分
     5 $month             // 返回该日期的月份部分 (1到12)
     6 $week              // 返回该日期是所在年的第几个星期 (0到53)
     7 $hour              // 返回该日期的小时部分
     8 $minute            // 返回该日期的分钟部分
     9 $second            // 返回该日期的秒部分 (以0到59之间的数字形式返回日期的第二部分,但可以是60来计算闰秒)
    10 $millisecond       // 返回该日期的毫秒部分 (0到999)
    11 $dateToString      // { $dateToString: {format:"",date:""} }
    12 // %Y  Year (4 digits, zero padded)                    0000-9999
    13 // %m  Month (2 digits, zero padded)                   01-12
    14 // %d  Day of Month (2 digits, zero padded)            01-31
    15 // %H  Hour (2 digits, zero padded, 24-hour clock)    00-23
    16 // %M  Minute (2 digits, zero padded)                  00-59
    17 // %S  Second (2 digits, zero padded)                  00-60
    18 // %L  Millisecond (3 digits, zero padded)            000-999
    19 // %j  Day of year (3 digits, zero padded)             001-366
    20 // %w  Day of week (1-Sunday, 7-Saturday)              1-7
    21 // %U  Week of year (2 digits, zero padded)            00-53
    22 // %%  Percent Character as a Literal                  %
    23 db.runoob.aggregate([{$project:{createDate:1,_id:0,dayOfYear:{$dayOfYear:"$createDate"},year:{$year:"$createDate"}}}])
    24 db.runoob.aggregate([{$project:{createDate:1,_id:0,newdate:{$dateToString:{format:"%Y",date:"$createDate"}}}}])

  • 相关阅读:
    ADO.NET中DataSet的应用(读书笔记5)
    ADO.NET中DataTable的应用(读书笔记4)
    如何在前端界面操作数据表(读书笔记3)
    如何在各类空间中输入输出数据(读书笔记2)
    关于利用input的file属性在页面添加图片的问题
    本地存储
    react
    微信开发
    node
    SVN和GIT
  • 原文地址:https://www.cnblogs.com/My-Sun-Shine/p/13511091.html
Copyright © 2011-2022 走看看