MongoDB:aggregate與aggregateCursor

bitsignal發表於2018-07-27

環境
mongos 3.0.14

aggregate

使用 aggregate 可以實現較為複雜的資料聚合操作,例如 彙總(count)、去重彙總(distinct count)、分組統計(group having)等。

aggregate 返回結果為陣列,需要注意資料大小不能超過16M。

例如:

$pipeline = [
            [`$match` => $tmpCondition],
            [`$group` => [
                `_id` => [`user_id`=>`$user_id`]
            ]],
            [`$group` => [
                `_id` => `_id.user_id`,
                `number` => [`$sum`=>1]
            ]]
        ];
$options = [
        `allowDiskUse`=>true,
        `cursor`=>[`batchSize`=>1]
];
        $data = MongoSvc::get(`user`)->user_info->aggregate($pipeline,$options);

aggregateCursor

對於大量返回結果的聚合,可以使用 aggregateCursor 返回遊標,可以避免資料大小超限。

aggregateCursor 的返回結果為遊標,可迴圈取數。

例如:

$pipeline = [
            [`$match` => $matchArr],
            [`$project` => [`id`=>1,`_id`=>0]],
            [`$group` => [
                `_id` => `$id`,
                `count` => [`$sum` => 1]
            ]],
            [`$match` => [
                `count` => [`$gt` => 1]
            ]]
        ];
        //這裡改為aggregateCursor用遊標迴圈獲取
        $data = MongoSvc::get(`user`)->user_info->aggregateCursor($pipeline);

pipeline 引數

  • $match
    條件匹配。
  • $addFields
    增加新欄位。
  • $count
    該stage的文件總數。
  • $group
    分組。
  • $limit
    限制數量。
  • $skip
    跳步。
  • $sort
    排序。
  • $out
    輸出結果到集合。
  • $project
    過濾欄位。

https://docs.mongodb.com/manu…

options 引數

  • explain boolean
    處理資訊。
  • allowDiskUse boolean
    true 可往磁碟寫臨時資料。
  • cursor
    cursor: { batchSize: <int> }
    給返回集合設定一個初始大小。
  • hint string or document
    強制指定索引。

https://docs.mongodb.com/manu…

查詢示例

彙總統計文件中某個欄位(如`sum`)的count值:

$pipeline = [
            [`$match` => $tmpCondition],
            [`$group` => [
                `_id` => [`sum`],
                `sum_value` => [`$sum` => `$money`]
            ]]
        ];

某列的去重後的資料:

$pipeline = [
            [`$match` => $tmpCondition],
            [`$group` => [
                `_id` => [`user_id` => `$user_id`]
            ]]
        ];

統計某列(如`user_id`)去重後的count值:

$pipeline = [
            [`$match` => $tmpCondition],
            [`$group` => [
                `_id` => [`user_id`=>`$user_id`]
            ]],
            [`$group` => [
                `_id` => `_id.user_id`,
                `number` => [`$sum`=>1]
            ]]
        ];
        
$pipeline = [
            [`$match` => $tmpCondition],
            [`$group` => [
                `_id`        => [`qid` => `$qid`],
                `max_number` => [`$max` => `$days`] 
            ]],
            [`$group` => [
                `_id` => [`number` => `$max_number`],
                `total` => [`$sum` => 1]
            ]]
        ];

統計分組後,各組內的某列彙總值:

$pipeline = [
            [`$match` => $tmpCondition],
            [`$group` => [
                `_id` => [`type` => `$type`],
                `sum_value` => [`$sum` => `$number`]
            ]]
        ];

相關文章