不能使聚合函数工作


Can't get aggregate functions to work

我是一个完全不熟悉Mongo的人,我在理解聚合框架方面遇到了一些严重的麻烦。我有一个文档,看起来像这样:

record {
    _id: '2013-04-22/tacos',
    first: {
        something: {0: 1, 1:4},
        somethingelse: {0: 18, 1:22}
    },
    second: {
        0: [11, 18, 7],
        1: [17, 9, 22]
    },
    metadata: {
        date: '2013-04-22'
    }
}

我想做的是首先得到每个项目的总和(因为这需要处理多个文档)。然后是first.somethingsecond.<whatever>.0second.<whatever>.1second.<whatever>.2中所有项目的总和。所以我正在寻找这样的结果(请原谅我的格式):

sum(first.something.0):      1
sum(first.something.1):      4
sum(second.0.0):            11
sum(second.0.1):            18
sum(second.0.2):             7
sum(second.1.0):            17
sum(second.1.1):             9
sum(second.1.2):            22
sum(first.something.all):    5
sum(second.<whatever>.0):   28
sum(second.<whatever>.1):   27
sum(second.<whatever>.2):   29

现在我只是想让前两个工作,在一个记录上,我得到了这个:

// $db is my collection, and is verified to work
$aggregate = array(
    '$group' => array(
        '_id' => '$metadata.date',
        'first_zero' => array('$sum' => 'first.something.0'),
        'first_one' => array('$sum' => 'first.something.1')
    ),
    '$match' => array(
        "metadata.date" => '2013-04-22'
    )
);
$cursor = $db->aggregate($aggregate);
var_dump($cursor);

但是我的输出告诉我exception: A pipeline stage specification object must contain exactly one field.。但是,如果我省略'$match'部分,它将返回first_zerofirst_one的int(0)记录,如下所示:

array(2) {
  ["result"]=>
  array(1) {
    [0]=>
    array(3) {
      ["_id"]=>
      string(10) "2013-04-22"
      ["clicks_zero"]=>
      int(0)
      ["clicks_one"]=>
      int(0)
    }
  }
  ["ok"]=>
  float(1)
}

所以我甚至不能让简单的部分工作。我哪里做错了?我能做second.<whatever>.0吗?

我不是Php专家,但是聚合查询应该是这样的:

  $aggregate = array(
      array('$group' => array(
          '_id' => '$metadata.date',
          'first_zero' => array('$sum' => 'first.something.0'),
          'first_one' => array('$sum' => 'first.something.1')
      )),
      array('$match' => array(
          "metadata.date" => '2013-04-22'
      ))
  );

每个管道操作符都应该在哈希/数组中。

编辑

但是,由于最后的$match管道,上述操作不会给您任何结果。在前面的管道中没有创建metadata.date字段,因此没有结果与您的查询匹配。正确的解决方案是:

  $aggregate = array(
      array('$match' => array(
          "metadata.date" => '2013-04-22'
      )),
      array('$group' => array(
          '_id' => '$metadata.date',
          'first_zero' => array('$sum' => 'first.something.0'),
          'first_one' => array('$sum' => 'first.something.1')
      ))
  );

这将给你:

{
"result" : [
    {
        "_id" : "2013-04-22",
        "first_zero" : 1,
        "first_one" : 4
    }
],
"ok" : 1
}