如何在PHP中使用MongoDB中的“group”?

时间:2014-03-28 09:50:39

标签: php mongodb

我在PHP中使用MongoDB,如何在下面申请?

db.event.group({
    keyf: function(doc) {
        return { 
            year: doc.created.getFullYear(),
            month: doc.created.getMonth() + 1,
            day: doc.created.getDate()
        }
    },
    reduce: function(curr, result){
        result.count++;
   },
    initial: {count: 0}
});

我在下面尝试过,但没有工作。看起来不支持keyf?

$keyf = 'function(doc){return {year: doc.created.getFullYear(), month: doc.created.getMonth()+1, day: doc.created.getDate()}}';
$initial = array('count' => 0);
$reduce = 'function(curr, result){result.count++;}';
$collection->group($keyf, $initial, $reduce);

2 个答案:

答案 0 :(得分:0)

看起来你基本上算了约会时的文件数量。

应该注意的是,group命令有很多缺陷,包括:

  • 不正式支持分片(警告不要使用分片)
  • 基本上是JavaScript
  • 基本上是地图缩减
  • 非常慢

这意味着它已被"弃用"支持聚合框架,在PHP中你可以使用:

$db->collection->aggregate(array(
    array('$group' => array(
        '_id' => array(
             'day' => array('$dayOfMonth' => '$created'),
             'month' => array('$month' => '$created'),
             'year' => array('$year' => '$created')
         ),
         'count' => array('$sum' => 1)
    ))
));

要了解我使用的操作符等,您可以在此处查看:

答案 1 :(得分:0)

PHP驱动程序确实有MongoCode类来构造所需的JavaScript值。

但你实际上更好使用.aggregate()命令,因为它是" native * code并且不依赖于JavaScript引擎。所以在产生结果时很多更快。

db.collection.aggregate([
    { "$group": {
        "_id": {
           "year": { "$year": "$created" },
           "month": { "$month": "$created" },
           "day": { "$dayOfMonth": "$created" }
        },
        "count": { "$sum": 1 }
    }}
])

数据问题


因此聚合函数可以正常工作,但您的测试数据似乎有问题。这是你给的:

db.post.insert({'field':'b', 'created':new Date('2014, 1, 1')});
db.post.insert({'field':'c', 'created':new Date('2014, 1, 1 11:11:11')});
db.post.insert({'field':'d', 'created':new Date('2014, 1, 1 12:00:00')});
db.post.insert({'field':'a', 'created':new Date('2014, 1, 2')});
db.post.insert({'field':'b', 'created':new Date('2014, 1, 2')})

这会产生数据:

{ "field" : "a", "created" : ISODate("2013-12-31T13:00:00Z") }
{ "field" : "b", "created" : ISODate("2013-12-31T13:00:00Z") }
{ "field" : "c", "created" : ISODate("2014-01-01T00:11:11Z") }
{ "field" : "d", "created" : ISODate("2014-01-01T01:00:00Z") }
{ "field" : "a", "created" : ISODate("2014-01-01T13:00:00Z") }
{ "field" : "b", "created" : ISODate("2014-01-01T13:00:00Z") }

所以看起来你正试图添加"小时"在同一天测试分组。但Date()的论据不正确。你想要这个:

db.post.insert({'field':'b', 'created':new Date('2014-01-01')});
db.post.insert({'field':'c', 'created':new Date('2014-01-01 11:11:11')});

所以整个日期都是一个字符串而不是"逗号"分隔值