mongodb聚合框架由两个字段组成

cas*_*stt 5 php codeigniter mongodb mongodb-php mongodb-query

我使用聚合和管道查询我的数据库,有两个单独的查询:

 $groups_q = array(
            '$group' => array(
                '_id' => '$group_name',
                'total_sum' => array('$sum' => 1)
                )
            );

  $statuses_q = array(
            '$group' => array(
                '_id' => '$user_status',
                'total_sum' => array('$sum' => 1)
                )
            );

$data['statuses'] = $this->mongo_db->aggregate('users',$statuses_q);
$data['groups'] = $this->mongo_db->aggregate('users',$groups_q);
Run Code Online (Sandbox Code Playgroud)

我得到了我想要的东西:

Array
(
[statuses] => Array
    (
        [result] => Array
            (
                [0] => Array
                    (
                        [_id] => Inactive
                        [total_sum] => 2
                    )

                [1] => Array
                    (
                        [_id] => Active
                        [total_sum] => 5
                    )

            )

        [ok] => 1
    )

[groups] => Array
    (
        [result] => Array
            (
                [0] => Array
                    (
                        [_id] => Accounting 
                        [total_sum] => 1
                    )

                [1] => Array
                    (
                        [_id] => Administrator
                        [total_sum] => 2
                    )

                [2] => Array
                    (
                        [_id] => Rep
                        [total_sum] => 1
                    )
            )

        [ok] => 1
    )

)
Run Code Online (Sandbox Code Playgroud)

我不想两次查询我的数据库.有没有更好的方法呢?如何通过一个查询完成它?我应该使用$ project运算符吗?

Ste*_*nie 13

您不能使用单个数据aggregate()来执行具有所需结果格式的两个分组计数.在第一次不再具有创建第二个计数所需的详细信息时对数据进行分组.

直截了当的方法是做两个查询,就像你已经在做的那样;-).

对替代品的思考

如果您真的想在一个聚合查询中获取信息,则可以在两个字段上进行分组,然后在应用程序代码中进行一些操作.如果组中有两个字段,则_id结果将是group_name和status的每个组合.

使用mongoshell的示例:

db.users.aggregate(
    { $group: {
         _id: { group_name: "$group_name", status: "$status" },
         'total_sum': { $sum: 1 }
    }}
)
Run Code Online (Sandbox Code Playgroud)

这似乎不是特别有效,并且适用于一些复杂的应用程序代码,因为您必须迭代结果两次才能获得预期的分组.

如果您只想要每个组的唯一名称而不是名称+计数,则可以$addToSet在单个组中使用.

另一个明显的选择是在应用程序代码中进行分组.做一个只find()投影group_namestatus字段,并在迭代结果时构建计数数组.