MongoDB 聚合管道的文档筛选($match)及分组统计($group)

上一篇我们了解了聚合管道的使用及聚合表达式的介绍,其中包含了聚合管道的语法:

        db.collection.aggregate(pipeline, options)

其中,

        collection:指的是集合或者视图

        pipeline:数组类型,是一组数据聚合操作。

                其基本语法:[ { <stage> }, ... ];由一组stage组成的数组。

        options: 可选,文档类型,其他的一些选项。

如果想进一步了解,可以参考:

MongoDB 聚合管道的使用及聚合表达式的介绍https://blog.csdn.net/m1729339749/article/details/130034020这篇我们主要介绍使用聚合管道实现文档筛选、分组统计:

一、准备工作

初始化零食数据

db.goods.insertMany([
    { "_id": 1,  name: "薯片", size: "S", quantity: 10, price: 8, expirationTime: ISODate( "2023-08-08T00:00:00Z" ) },
    { "_id": 2,  name: "薯片", size: "L", quantity: 8, price: 12, expirationTime: ISODate( "2023-08-08T00:00:00Z" ) },
    { "_id": 3,  name: "牛肉干", size: "L", quantity: 5, price: 30, expirationTime: ISODate( "2023-10-10T00:00:00Z" ) },
    { "_id": 4,  name: "可口可乐", size: "S", quantity: 10, price: 3, expirationTime: ISODate( "2025-01-06T00:00:00Z" ) },
    { "_id": 5,  name: "可口可乐", size: "L", quantity: 6, price: 10, expirationTime: ISODate( "2025-01-06T00:00:00Z" ) },
    { "_id": 6,  name: "旺仔牛奶", size: "L", quantity: 10, price: 5, expirationTime: ISODate( "2023-08-10T00:00:00Z" )}
])

二、文档筛选($match)

语法:{ $match: { <query> } }

过滤文档,只有匹配的文档才能进入到下一个处理阶段

其中,query 代表的是查询过滤器,可以参考:

MongoDB 查询文档(1)https://blog.csdn.net/m1729339749/article/details/129965699MongoDB 查询文档(2)https://blog.csdn.net/m1729339749/article/details/129971708例子:统计型号是L的商品都有哪些

db.goods.aggregate([
    {
        $match: { "size": "L" },
    },
    {
        $group: {
            "_id": "$size",
            "goods": { "$addToSet": "$name" }
        }
    }
])

先过滤出产品型号是L的商品,再进行分组统计。

聚合查询的结果如下:

{ "_id" : "L", "goods" : [ "薯片", "牛肉干", "可口可乐", "旺仔牛奶" ] }

二、分组统计($group)

语法:

{
  $group:
    {
      _id: <expression>, // Group key
      <field1>: { <accumulator1> : <expression1> },
      ...
    }
 }

其中_id对应的expression对应的是分组字段。

field是定义的聚合字段,需要通过accumulator运算符计算得到。

下面我们介绍不同的accumulator运算符:

1、$addToSet

语法:{ $addToSet: <expression> }

返回一个数组,其中数组中的值不会重复(会去重),数组中的值来源于组内每个文档使用表达式计算后的结果。

例子:统计一下不同零食都有哪些型号

db.goods.aggregate([
    {
        $group: { 
            "_id": "$name", 
            "totalSize": { $addToSet: "$size" }
        }
    }
])

按照名称进行分组,把分组内文档的型号字段对应的数据进行汇总后放入新的字段。

聚合查询的结果如下:

{ "_id" : "牛肉干", "totalSize" : [ "L" ] }
{ "_id" : "薯片", "totalSize" : [ "S", "L" ] }
{ "_id" : "可口可乐", "totalSize" : [ "L", "S" ] }
{ "_id" : "旺仔牛奶", "totalSize" : [ "L" ] }

2、$avg

语法:{ $avg: <expression> }

求组内所有文档使用表达式计算后的结果的平均值。

例子:统计一下不同型号零食的平均数量

db.goods.aggregate([
    {
        $group: { 
            "_id": "$size", 
            "avgQuantity": { $avg: "$quantity" }
        }
    }
])

按照型号进行分组,分组之后按照数量求平均值。

聚合查询的结果如下:

{ "_id" : "S", "avgQuantity" : 10 }
{ "_id" : "L", "avgQuantity" : 7.25 }

3、$max

语法:{ $max: <expression> }

求组内所有文档使用表达式计算后的结果的最大值

例子:统计一下不同零食的最高价格

db.goods.aggregate([
    {
        $group: { 
            "_id": "$name", 
            "maxPrice": { $max: "$price" }
        }
    }
])

按照名称进行分组,分组之后按照价格求最大值。

聚合查询的结果如下:

{ "_id" : "薯片", "maxPrice" : 12 }
{ "_id" : "牛肉干", "maxPrice" : 30 }
{ "_id" : "可口可乐", "maxPrice" : 10 }
{ "_id" : "旺仔牛奶", "maxPrice" : 5 }

4、$min

语法:{ $min: <expression> }

求组内所有文档使用表达式计算后的结果的最小值

例子:统计一下不同零食的最低价格

db.goods.aggregate([
    {
        $group: { 
            "_id": "$name", 
            "mixPrice": { $min: "$price" }
        }
    }
])

按照名称进行分组,分组之后按照价格求最小值。

聚合查询的结果如下:

{ "_id" : "薯片", "mixPrice" : 8 }
{ "_id" : "牛肉干", "mixPrice" : 30 }
{ "_id" : "可口可乐", "mixPrice" : 3 }
{ "_id" : "旺仔牛奶", "mixPrice" : 5 }

5、$sum

语法:{ $sum: <expression> }

        或者 { $sum: [ <expression1>, <expression2> ... ] }

求组内所有文档使用表达式计算后的结果求和

例子:统计一下不同零食的总数量

db.goods.aggregate([
    {
        $group: { 
            "_id": "$name", 
            "totalQuantity": { $sum: "$quantity" }
        }
    }
])

按照名称进行分组,分组之后按照数量求和。

聚合查询的结果如下:

{ "_id" : "薯片", "totalQuantity" : 18 }
{ "_id" : "牛肉干", "totalQuantity" : 5 }
{ "_id" : "可口可乐", "totalQuantity" : 16 }
{ "_id" : "旺仔牛奶", "totalQuantity" : 10 }
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值