Php Mongodb按列聚合/分组并计算特定列

Php Mongodb按列聚合/分组并计算特定列,php,mongodb,aggregation-framework,Php,Mongodb,Aggregation Framework,我们已经设置了一个基本应用程序,它将事件写入mongo实例。下面是一个示例: "_id" : ObjectId("50fee761472870a3d610956e"), "user_id" : "pa-XXXXXXXXX", "event_id" : 1, "date_created" : 1337798856, "url" : "http://news.yahoo.com/australian-tycoon-worlds-richest-woman-103810

我们已经设置了一个基本应用程序,它将事件写入mongo实例。下面是一个示例:

"_id" : ObjectId("50fee761472870a3d610956e"),
    "user_id" : "pa-XXXXXXXXX",
    "event_id" : 1,
    "date_created" : 1337798856,
    "url" : "http://news.yahoo.com/australian-tycoon-worlds-richest-woman-103810206.html"
我们要做的是检索按URL和特定事件id计数分组的结果。与事件组一样,事件组a可能由事件组ID 1,6,35组成,事件组b可能由2,66103组成。示例输出如下所示:

{
    url: "http://news.yahoo.com/australian-tycoon-worlds-richest-woman-103810206.html",
    event_grouping_a: 46,
    event_grouping_b: 34
},
{
    url: "http://news.yahoo.com/another-cool-story",
    event_grouping_a: 105,
    event_grouping_b: 59
}
{
    url: "http://news.yahoo.com/australian-tycoon-worlds-richest-woman-103810206.html",
    event_grouping_a: 46
    event_grouping_b: 0
},
{
    url: "http://news.yahoo.com/australian-tycoon-worlds-richest-woman-103810206.html",
    event_grouping_a: 0
    event_grouping_b: 34
},
...
您知道如何执行这种类型的聚合/分组吗?最终的目标是在PHP中使用它,但我在mongod控制台中使用它却毫无用处。我可以让它按URL分组,但我不能让它在单个父URL下同时显示两种事件类型。它吐出这样的东西:

{
    url: "http://news.yahoo.com/australian-tycoon-worlds-richest-woman-103810206.html",
    event_grouping_a: 46,
    event_grouping_b: 34
},
{
    url: "http://news.yahoo.com/another-cool-story",
    event_grouping_a: 105,
    event_grouping_b: 59
}
{
    url: "http://news.yahoo.com/australian-tycoon-worlds-richest-woman-103810206.html",
    event_grouping_a: 46
    event_grouping_b: 0
},
{
    url: "http://news.yahoo.com/australian-tycoon-worlds-richest-woman-103810206.html",
    event_grouping_a: 0
    event_grouping_b: 34
},
...

上面的两个应该合并成1,但我一辈子都想不出来。。。有什么建议吗?

我不一定喜欢使用
$或
语句来实现此功能,但是如果您使用的是1.3+mongo驱动程序,则此查询应该可以在php中实现:

$mongo = new MongoClient('dbinfo');
$collection = $mongo->selectCollection( 'dbName', 'collectionName' );

$pipeline = array(
    array( 
        '$group' => array(
            '_id' => '$url',
            'event_grouping_a' => array( 
                '$sum' => array( 
                    '$cond' => array( 
                        array( '$or' => array(
                            array( '$eq' => array( '$event_id', 1 ) ),
                            array( '$eq' => array( '$event_id', 6 ) ),
                            array( '$eq' => array( '$event_id', 35 ) )
                        ) ), 1, 0 ) 
                )   
            ),
            'event_grouping_b' => array(
                '$sum' => array(
                    '$cond' => array(
                        array( '$or' => array(
                            array( '$eq' => array( '$event_id', 2 ) ),
                            array( '$eq' => array( '$event_id', 66 ) ),
                            array( '$eq' => array( '$event_id', 103 ) )
                        ) ), 1, 0 )
                )
            )
        )
    )
);
$results = $collection->aggregate( $pipeline );
--


应该包括您在控制台中尝试的查询。谢谢!如果记录集跨越200-400K条记录,您是否觉得此解决方案可以扩展?我建议您评估索引的使用,这样您就不会不必要地进行完全扫描。您应该没问题,但是您可能还想使用upserts在单独的集合中预聚合这些数据,mongo文档中有一些示例。