duandian8110 2013-01-02 10:08
浏览 86
已采纳

MongoDB聚合PHP,按小时分组

I have documents with the following format

{
  "_id" : ObjectId("12e123123123123123"),
  "client_id" : "12345667889",
  "resource" : "test/test",
  "version" : "v2",
  "ts" : new Date("Wed, 02 Jan 2013 15:34:58 GMT +08:00")
}

The ts is a MongoDate() field.

I am trying to use MongoDB aggregate function in php to group by client_id and hour and count usage to display in a table/graph

This is my current attempt

$usage = $this->db->Usage->aggregate(array(array(
  '$project' => array(
    'hour' => array(
      'years' => array( '$year' => '$ts' ),
      'months' => array( '$month' => '$ts' ),
      'days' => array( '$dayOfMonth' => '$ts' ),
      'hours' => array( '$hour' => '$ts' ),
    )
  ),
  '$group' => array(
    '_id' => array(
      'client_id' => '$client_id',
      'hour' => '$hour',
    ),
   'number' => array('$sum' => 1),
  )
)));

Unfortunately my response I am getting back is just grouping by the client_id and nothing else.

[result] => Array
    (
        [0] => Array
            (
                [_id] => Array
                    (
                        [client_id] => adacf8deba7066e4
                    )

                [number] => 12
            )

    )

Anyone able to point me in the right direction, or have another solution to group by hour?

--Fixed-- PHP requires that you put each pipeline in a separate array as well as putting the whole thing in an array. see update solution below with help from JohnnyHK

$usage = $this->db->Usage->aggregate(array(array(
        '$project' => array(
            'client_id' => 1,
            'hour' => array(
                'years' => array( '$year' => '$ts' ),
                'months' => array( '$month' => '$ts' ),
                'days' => array( '$dayOfMonth' => '$ts' ),
                'hours' => array( '$hour' => '$ts' ),
            )
        )),array(
        '$group' => array(
            '_id' => array(
                'client_id' => '$client_id',
                'hour' => '$hour',
            ),
            'number' => array('$sum' => 1),
        )
    )));
  • 写回答

1条回答 默认 最新

  • duanmaduan1848 2013-01-02 14:09
    关注

    It shouldn't create the results you're seeing, but you do need to include client_id in your $project operator so that it's available to the $group operator.

    '$project' => array(
      'client_id' => 1,
      'hour' => array(
        'years' => array( '$year' => '$ts' ),
        'months' => array( '$month' => '$ts' ),
        'days' => array( '$dayOfMonth' => '$ts' ),
        'hours' => array( '$hour' => '$ts' ),
      )
    ),
    

    The shell equivalent worked after I made that change:

    db.test.aggregate(
        { $project: {
            hour: {
                years: {$year: '$ts'},
                months: {$month: '$ts'},
                days: {$dayOfMonth: '$ts'},
                hours: {$hour: '$ts'}
            },
            client_id: '$client_id'
        }},
        { $group: {
            _id: { client_id: '$client_id', hour: '$hour' },
            number: { $sum: 1}
        }})
    

    returned:

    {
      "result": [
        {
          "_id": {
            "client_id": "12345667889",
            "hour": {
              "years": 2013,
              "months": 1,
              "days": 2,
              "hours": 7
            }
          },
          "number": 1
        }
      ],
      "ok": 1
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化