• mongodb 聚合(aggregate)


      

       MongoDB中文手册|官方文档中文版 https://docs.mongoing.com/

      聚合操作处理数据记录和 return 计算结果。聚合操作将来自多个文档的值组合在一起,并且可以对分组数据执行各种操作以返回单个结果。

       MongoDB 提供了三种执行聚合的方法:聚合管道,map-reduce function和单一目的聚合方法。

      管道使用MongoDB中的原生操作提供有效的数据聚合,并且是MongoDB中数据聚合的首选方法。

      一、聚合管道

      MongoDB 的Aggregation framework是以数据处理管道的概念为蓝本的。文档进入多阶段管道,将文档转换为聚合结果。

      聚合(aggregate)主要用于计算数据,类似sql中的sum()、avg()

      语法:db.集合名称.aggregate([{管道:{表达式}}])

      管道在MongoDB中一般用于将当前命令的输出结果作为下一个命令的输入

      常用管道

      1、$group:将集合中的文档分组,可用于统计结果

      2、$match:过滤数据,只输出符合条件的文档

      3、$project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果

      4、$sort:将输入文档排序后输出

      5、$limit:限制聚合管道返回的文档数

      6、$skip:跳过指定数量的文档,并返回余下的文档

      7、$unwind:将数组类型的字段进行拆分

      

      表达式:处理输入文档并输出

      语法:表达式:'$列名'

      常用表达式

      1、$sum:计算总和,$sum:1同count表示计数

      2、$avg:计算平均值

      3、$min:获取最小值

      4、$max:获取最大值

      5、$push:在结果文档中插入值到一个数组中

      6、$first:根据资源文档的排序获取第一个文档数据

      7、$last:根据资源文档的排序获取最后一个文档数据

      $group

      将集合中的文档分组,可用于统计结果,

      _id表示分组的依据,使用某个字段的格式为'$字段'

      例如:统计订单表中每天订单的数量:

    db.order.aggregate(
    [
       { $group: { _id: "date", count: { "$sum": 1 } } }
    ])

      Group by null

      将集合中所有文档分为一组

      求订单总数

    db.order.aggregate(
    [
       { $group: {_id:null, count: { "$sum": 1 } } }
    ])

      透视数据

      统计detail10集合中,直播和视频的标题

    db.detail10.aggregate(
    [
       { $match: { name: '央视新闻',date:'2020-10-08',tag:{'$in':['视频','直播']}} },
       { $group: { _id: '$tag', title: { '$push': '$title'} } }
    ])

    结果:

    { "_id" : "直播", "title" : [ "《新闻1+1》| 急救设备,能成为公共场所的“标配”吗?", "夜游西安乐华城 “月赏”秦汉古风新 国潮", "多地直击假日返程高峰", "长假首日 品中国国际动漫节的“中国风”", "《新闻1+1》| 急救设备,能成为公共场所的“标配”吗?", "夜游西安乐华城 “月赏”秦汉古风新国潮", "多地直击假日返程高峰", "长假首日 品中国国际动漫节的“中国风”" ] }
    { "_id" : "视频", "title" : [ "假期要结束了朱广权段子还在", "天问一号飞控团队有成员生于1998年", "美加州出现血红色满月", "广州灯光秀夜空拼出钟南山肖像", "来自新闻联播的双节祝福", "曾在武汉共同抗疫他们 结婚了!", "假期要结束了朱广权段子还在", "天问一号飞控团队有成员生于1998年", "美加州出现血红色满月", "广州灯光秀夜空拼出钟南山肖像", "来自新闻联播的双节祝福", "曾在武汉共同抗疫他们 结婚了!" ] }

       $match

       用于过滤数据,只输出符合条件的文档

       使用MongoDB的标准查询操作

        例如,查询name为央视新闻,日期为2020-10-08的记录中每个tag值对应的记录数量

    db.detail10.aggregate(
    [
       { $match: { name: "央视新闻",date:'2020-10-08' } },
    
       { $group: { _id: "$tag", count: { "$sum": 1 } } }
    ])

       $project

       修改输入文档的结构,如重命名、增加、删除字段、创建计算结果

      

    db.detail10.aggregate(
    [
       { $match: { name: '央视新闻',date:'2020-10-08',tag:{'$in':['视频','直播']}} },
       { $group: { _id: "$tag", count: { "$sum": 1 } } },
       { $project: { _id: 0, count:1} }
    ])

      $sort

      将输入文档排序后输出

      查询tag对应记录数量,按统计数量升序

    db.detail10.aggregate(
    [
       { $match: { name: "央视新闻",date:'2020-10-08' } },
    
       { $group: { _id: "$tag", count: { "$sum": 1 } } },
    
       {$sort:{count:1}}
    ])

      结果:

    { "_id" : "小视频", "count" : 6 }
    { "_id" : "直播", "count" : 8 }
    { "_id" : "视频", "count" : 12 }
    { "_id" : "微头条", "count" : 16 }
    { "_id" : "文章", "count" : 366 }

      $limit

      限制聚合管道返回的文档数,

      例如返回上面返回结果2条记录:

    db.detail10.aggregate(
    [
       { $match: { name: "央视新闻",date:'2020-10-08' } },
    
       { $group: { _id: "$tag", count: { "$sum": 1 } } },
    
       {$sort:{count:1}},
    
       {$limit:2}    
    ])

      结果:

    { "_id" : "小视频", "count" : 6 }
    { "_id" : "直播", "count" : 8 }

      

      $unwind

      语法1

      将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值

      构造数据:

    db.test.insert({item:'新闻',tag:['视频','直播','文章','小视频','微头条']})
    db.test.aggregate([{$unwind:'$tag'}])
    结果: {
    "_id" : ObjectId("5feadb227aa0648519c1ad4a"), "item" : "新闻", "tag" : "视频" } { "_id" : ObjectId("5feadb227aa0648519c1ad4a"), "item" : "新闻", "tag" : "直播" } { "_id" : ObjectId("5feadb227aa0648519c1ad4a"), "item" : "新闻", "tag" : "文章" } { "_id" : ObjectId("5feadb227aa0648519c1ad4a"), "item" : "新闻", "tag" : "小视频" } { "_id" : ObjectId("5feadb227aa0648519c1ad4a"), "item" : "新闻", "tag" : "微头条" }

       语法2:

        对某字段值进行拆分,

        处理空数组、非数组、无字段、null情况

      

    db.inventory.aggregate([{
        $unwind:{
            path:'$字段名称',
            preserveNullAndEmptyArrays:<boolean>#防止数据丢失
        }
    }])

      构造数据:

    db.test.insert([
    { "_id" : 1, "item" : "a", "tag": ['视频','直播','文章','小视频','微头条'] },
    { "_id" : 2, "item" : "b", "tag" : [ ] },
    { "_id" : 3, "item" : "c", "tag": "视频" },
    { "_id" : 4, "item" : "d" },
    { "_id" : 5, "item" : "e", "size" : null }
    ])

      使用语法1查询

    db.test.aggregate([{$unwind:'$tag'}])

    结果:

    { "_id" : 1, "item" : "a", "tag" : "视频" }
    { "_id" : 1, "item" : "a", "tag" : "直播" }
    { "_id" : 1, "item" : "a", "tag" : "文章" }
    { "_id" : 1, "item" : "a", "tag" : "小视频" }
    { "_id" : 1, "item" : "a", "tag" : "微头条" }
    { "_id" : 3, "item" : "c", "tag" : "视频" }

    查看查询结果,发现对于空数组、无字段、null的文档,都被丢弃了

    如何能不丢弃呢?使用语法2

    db.test.aggregate([{$unwind:{path:'$tag',preserveNullAndEmptyArrays:true}}])
    { "_id" : 1, "item" : "a", "tag" : "视频" }
    { "_id" : 1, "item" : "a", "tag" : "直播" }
    { "_id" : 1, "item" : "a", "tag" : "文章" }
    { "_id" : 1, "item" : "a", "tag" : "小视频" }
    { "_id" : 1, "item" : "a", "tag" : "微头条" }
    { "_id" : 2, "item" : "b" }
    { "_id" : 3, "item" : "c", "tag" : "视频" }
    { "_id" : 4, "item" : "d" }
    { "_id" : 5, "item" : "e", "size" : null }

      

      

     

  • 相关阅读:
    ubuntu使用squid搭建代理
    CentOS 7 安装配置带用户认证的squid代理服务器
    Squid配置之使用帐号密码验证
    Centos 7 关闭selinux and firewall
    linux虚拟机桥接网络配置
    常用插件html
    nodejs express 上传文件自定义文件名和上传路径
    nodejs express 部署
    centos7 mysql 各种报错
    centos7通过yum安装JDK1.8
  • 原文地址:https://www.cnblogs.com/shaosks/p/14206470.html
Copyright © 2020-2023  润新知