初识MongoDB(十三) MongoDB管道操作符二

$group

基本操作

$group 可以用来对文档进行分组,比如我想将订单按照城市分组,并统计出每个城市的订单数量:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",count:{$sum:1}}})

我们将要分组的字段传递给 $group 函数的 _id 字段,然后每当查到一个,就给 count 加1,这样就可以统计出每个城市的订单数量。

算数操作符

通过算术操作符我们可以对分组后的文档进行求和或者求平均数。比如我想计算每个城市订单运费总和,如下:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",totalFreight:{$sum:"$freight"}}})

先按地址分组,再求和。也可以计算每个城市订单运费的平均数,如下:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",avgFreight:{$avg:"$freight"}}})

先按地址分组,然后再计算平均数。

极值操作符

极值操作符用来获取分组后数据集的边缘值,比如获取每个城市最贵的运费,如下:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",maxFreight:{$max:"$freight"}}})

查询每个城市最便宜的运费:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",minFreight:{$min:"$freight"}}})

按城市分组之后,获取每个城市第一个运费:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",firstFreight:{$first:"$freight"}}})

获取分组后每个城市的最后一个运费:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",lastFreight:{$last:"$freight"}}})

数据操作符

$addToSet 可以将分组后的某一个字段放到一个数组中,但是重复的元素将只出现一次,而且元素加入到数组中的顺序是无规律的。比如将分组后的每个城市的运费放到一个数组中,如下:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",freightArr:{$addToSet:"$freight"}}})

结果如下:

重复的 freight 不会被添加进来。

$push 则对重复的数据不做限制,都可以添加进来,如下:

db.agg_2.aggregate({$group:{_id:"$orderAddressL",freightArr:{$push:"$freight"}}})

结果如下:

$unwind

$unwind 用来实现对文档的拆分,可以将文档中的值拆分为单独的文档。比如数据如下:

{
    "_id":ObjectId("61a73ec1fcabfe7d198aac98"),
    "name":"鲁迅",
    "books":[
        {
            "name":"呐喊",
            "publisher":"花城出版社"
        },
        {
            "name":"彷徨",
            "publisher":"南海出版社"
        }
    ]
}

使用 $unwind 命令将其拆分为独立文档,如下:

db.agg_3.aggregate({$unwind:"$books"})

拆分结果如下:

{
    "_id":ObjectId("61a73ec1fcabfe7d198aac98"),
    "name":"鲁迅",
    "books":{
        "name":"呐喊",
        "publisher":"花城出版社"
    }
}
{
    "_id":ObjectId("61a73ec1fcabfe7d198aac98"),
    "name":"鲁迅",
    "books":{
        "name":"彷徨",
        "publisher":"南海出版社"
    }
}

其他操作符

$sort 操作符可以对文档进行排序,如下:

db.agg_2.aggregate({$sort:{orderAddressL:1}})

用法和我们之前介绍普通搜索中的一致。可以按照存在的字段排序,也可以按照重命名的字段排序,如下:

db.agg_2.aggregate({$project:{addr:"$orderAddressL"}},{$sort:{addr:1}})

1表示升序,-1表示降序。

$limit 返回结果中的前n个文档,如下表示返回结果中的前3个文档:

db.agg_2.aggregate({$project:{addr:"$orderAddressL"}},{$limit:3})

$skip 表示跳过前n个文档,比如跳过前2个文档,如下:

db.agg_2.aggregate({$project:{addr:"$orderAddressL"}},{$skip:2})

$skip 的效率低,要慎用。

总结

在管道开始执行的阶段,尽可能过滤掉足够多的数据,这样做有两个好处:

1. 只有从集合中直接查询时才会使用索引,尽早执行过滤可以让索引发挥作用。

2. 该过滤的数据过滤掉之后,也可以降低后面管道的执行压力。另外,MongoDB不允许一个聚合操作占用过多的内存,如果有一个聚合操作占用了超过20%的内存,则会直接报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值