MongoDB管道

作者: 缘来是你ylh | 来源:发表于2019-03-08 06:15 被阅读20次

    今天和大家分享mongodb中管道,老规矩贴上官方 文档

    我们从聚合慢慢引入管道的概念

    mongo中常见的聚合有count,distinct,group,mapReduce

    我们先创建好测试数据,查看一下

    > db.student.find().pretty()
    { "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 }
    { "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 }
    { "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 }
    { "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 }
    

    下面来介绍个方法的使用

    1.count 统计文档数量

    > db.student.count()    //统计文档数量
    4
    > db.student.count({"age": {$gte: 20}})   //统计年龄大于等于20的文档数量
    3
    

    2.countDocuments

    mongo4.0以上的版本已经不推荐使用count了,取而代之的是countDocuments

    > db.student.countDocuments({"age": {$gte: 20}})
    3
    

    3.distinct 获取指定字段的值的分布(去重)

    > db.student.distinct("scores")
    [ 98, 89, 91 ]    
    

    4.aggregate(管道)替代group,老板本mongo是有直接的命令group来分组的

    官方原文

    DEPRECATED SINCE VERSION 3.4

    Mongodb 3.4 deprecates the group command. Use db.collection.aggregate() with the $group stage or db.collection.mapReduce() instead.

    mongodb3.4版本废弃了group命令,取而代之的是db.collection.aggregatedb.collection.mapReduce

    > db.student.aggregate([ {$group: {_id: "$scores", person_num : {$sum: "$scores"}}} ])
    { "_id" : 91, "person_num" : 182 }
    { "_id" : 89, "person_num" : 89 }
    { "_id" : 98, "person_num" : 98 }
    

    类似于mysql的 select scores, count(*) as person_num from student group by scores

    $sum后面的是什么意思呢,对scores字段求和

    > db.student.aggregate([ 
        {$match: {"name": {$in: ["tom", "jack", "luna"]}}},  
        {$group: {_id: "$scores", person_num : {$sum: 1}}} 
    ])
    { "_id" : 91, "person_num" : 1 }
    { "_id" : 89, "person_num" : 1 }
    { "_id" : 98, "person_num" : 1 }
    

    这里就是一个典型的管道使用情况了, 以上命令执行了两步,在一个管道里面执行

    • 先匹配name值在数组["tom", "jack", "luna"]的文档
    • 再分组统计

    既然说到了分组group我就顺便再讲几个聚合方法吧

    根据年龄分组求平均值实例

    > db.student.find()
    { "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 }
    { "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 }
    { "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 }
    { "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 }
    > db.student.aggregate([{$group : {_id: "$age", avg_scores: {$avg: "$scores"}}}])
    { "_id" : 19, "avg_scores" : 91 }
    { "_id" : 21, "avg_scores" : 90 }
    { "_id" : 20, "avg_scores" : 98 }
    

    根据分数分组,求组内最小的分数

    > db.student.aggregate([{$group : {_id: "$scores", min_scores: {$min: "$age"}}}])
    { "_id" : 91, "min_scores" : 19 }
    { "_id" : 89, "min_scores" : 21 }
    { "_id" : 98, "min_scores" : 20 }
    

    对应的$max方法语法一直

    总结:

    表达式 描述 语法
    $sum 计算总和 db.mycol.aggregate([{group : {_id : "by_field", alias_name : {sum : "field"}}}])
    $avg 计算平均值 db.mycol.aggregate([{group : {_id : "by_field", alias_name : {avg : "field"}}}])
    $min 获取集合中所有文档对应值得最小值 db.mycol.aggregate([{group : {_id : "by_field", alias_name : {min : "field"}}}])
    $max 获取集合中所有文档对应值得最大值 db.mycol.aggregate([{group : {_id : "by_field", alias_name : {max : "field"}}}])

    $by_field是分组的字段,比如按年龄分组就改成$age

    alias_name 是统计数据之后的一个别名,类似于mysql的as

    $field 是聚合的字段 比如按年龄分组后取分组中scores的最大值就把$field改为$scores

    管道中的排序

    文档的排序也是要通过管道来实现的

    > db.student.aggregate([{$sort : {age : 1}}])
    { "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 }
    { "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 }
    { "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 }
    { "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 }
    

    官方原文

    For the field or fields to sort by, set the sort order to 1 or -1 to specify an ascending or descending sort respectively, as in the following example:

    1是升序asc,-1是降序desc

    最后说一下管道中的其它操作

    • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
    • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
    • $limit:用来限制MongoDB聚合管道返回的文档数。
    • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
    • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
    • $group:将集合中的文档分组,可用于统计结果。
    • $sort:将输入文档排序后输出。
    • $geoNear:输出接近某一地理位置的有序文档

    本文写的有点乱,希望看官不要见怪!!!

    相关文章

      网友评论

        本文标题:MongoDB管道

        本文链接:https://www.haomeiwen.com/subject/wqhpuqtx.html