php7 mongodb 使用(三)原生驱动下聚合操作与管道操作

7 篇文章 0 订阅

1,mongodb 3.2版本才有聚合操作,如果你是用的版本低于3.2,请先升级版本。
代码基于 php7 原生驱动,php5或者mongodb library 类库的,请出门从外面关上门,不送。

2,使用的php操作类 请先查看本文的上一章节

3,在上一章节中 我们介绍 Command 命令时候使用了一个例子
统计一个集合下的数据量  类似mysql 的 count

$cmd=["count" => $table,"query" =>$filter];
$model->query('',$cmd,[],'command');
$cmd中 count指定某个集合   query 是对集合进行过滤  $filter和普通查询中的使用方法一样。 

4,这个例子也可以使用聚合来实现,实现的基础操作也是基于 manager()->executeCommand

$cmd=[
    'aggregate' => $table,          /*指定对那个集合进行 聚合操作*/
    'pipeline' => [
        ['$match' => $filter],     /*过滤数据  $filter 的具体用法 参照 上一章节的查询*/        
        ['$group' => [
                '_id' => '$type',        /*指定字段 group分组  这里的 '_id' 不是指代集合中主键,你可以把它理解为语法关键字  $type 才是分组字段 $type可以null 意思就是不按字段分组,把整个表视作一个组*/
                'count' => [ '$sum' => 1]     /* 这里的 'count' 是自定义的显示字段,和数据库的的列没有直接关系,相当于 mysql里面的  sum(1) as count,sum 是求和,但是结果是行数   */
        ]]     
     ],   
    'cursor' => new \stdClass()
$res=$model->query('',$cmd,[],'command');

/*这个 pipeline下的结构体很容易搞错格式  [['$match'=>[]],['$group'=>[]]]  一定要按这个格式,丝毫不能差,否则php一般会报 CommandException: 'pipeline' option must be specified as an array in  类似的错误 */

返回值是一个array数组
Array
(
    [0] => stdClass Object
        (
            [_id] => 
            [count] => 273
        )
)

这个示例中  ['$sum'=>1] 是聚合操作函数  类似 mysql中  sum() 求和函数,但是mongodb中是没有count()这个计数函数的。
$avg  $min  $max 这三个也是合法的聚合函数。

5,pipeline 英文原意是管道, 你可以数据就像流水一样,依次从pipeline的每一个子项流过,依次进行处理,
就像整个实例中  数据先经过 ['$match' => $filter] 进行过滤处理,再经过['$group' =>[]]进行分组加工。
mysql中groupby 后有having 对分组后的数据进行再次过滤。mongodb可以基于管道的原理,可以在group后继续用 $match方法进行过滤。
类似的函数还有 $project 和普通查询用法一样,就是控制字段的显示。这个方法可以方法 放在  $match前面也可以方法 $group 的后面。

$cmd=[
            "aggregate" => 'user_log_04_19',
            "pipeline" =>[
                ['$project'=>['_id'=>1,'path'=>1,'ip'=>1,'time'=>1]],  /*指定只显示四个字段*/
                ['$match'=>['ip'=>['$regex'=>'^222.']]],   /*ip按条件过滤*/
                ['$group'=>[
                    '_id'=>'$path',
                    'count'=>['$sum'=>1],
                    'ip'=>['$first'=>'$ip'],
                    'time'=>['$last'=>'$time']
                ]],
                ['$match'=>['count'=>['$gt'=>10]]],   /*类似mysql中的having,对分组后的数据继续过滤*/
                ['$project'=>['_id'=>0,'count'=>1,'ip'=>1,'time'=>1]],  /*字段path已经聚合,显示成_id 但是需要隐藏*/
                ['$sort'=>['_id' => -1]],  /*排序*/
                ['$skip'=>0],
                ['$limit'=>10],
                ['$count'=>'count']   /*count方法对统计结果集 赋值给count 字段*/
            ],
            'cursor' => new \stdClass()
        ];
$res=$model->query('',$cmd,[],'command');

这个实例完整的演示了,管道参数传递,多次使用$match数据过滤和$project字段显示隐藏,以及多种聚合操作函数。
更多聚合操作函数以及管道函数

6,distinct  去重复,这个可以用聚合实现,要去重的字段进行聚合后使用管道筛选数据就可以,单独说这个问题,是因为mongodb官方还提供了另一种操作方式。


$cmd=["distinct" => $table,'key'=>$field,"query" =>$filter];     /*key 就是要去重的字段 这个方法实际是上和count一样都是 command命令 */
$model->query('',$cmd,[],'command');

总结 为什么很多人都吐槽 php7  mongodb的原生驱动不好用,因为官方文档太简略,需要程序员自己去摸索实践。我也是经过一个星期的功夫,反复测试总结才有了这三篇干货文章,希望能让让看到的人少走一些弯路。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hangbobo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值