我有一个类似的"问题":MongoDB、PHP每天获得唯一访问数
我的php查询:
array(
array('$match' => array('date' => array('$gte' => $dateStart, '$lte' => $dateEnd))),
array('$project' => array('day' => array('$dayOfMonth' => '$date'))),
array('$group' => array('_id' => array('day' => '$day', 'uniqueVisitors' => '$ip'), 'count' => array('$sum' => 1))),
array('$group' => array('_id' => array('day' => '$_id.day'), 'count' => array('$sum' => 1))),
array('$sort' => array('_id.day' => 1)),
);
这只显示1作为计数,如果我删除第二个组数组,我得到ip计数,但不是唯一的。有人能看到我的失败吗?(
问好,
在你复制的代码中有一些不必要的步骤,所以基本上你的管道应该是这样的
$pipeline = array(
array(
'$match' => array(
'date' => array('$gte' => $dateStart, '$lte' => $dateEnd )
)
),
array(
'$group' => array(
'_id' => array(
'day' => array( '$dayOfMonth' => '$date' ),
'uniqueVisitors' => '$ip'
)
)
),
array(
'$group' => array(
'_id' => '$_id.day',
'count' => array('$sum' => 1)
)
),
array( '$sort' => array('_id' => 1) )
);
第一个 $group
缩小了rage中每月每天的实际唯一"ip"值。假设您有一个月在这个范围内,或者使用 $dayOfYear
。
现在这些项目在管道文档中是"唯一的",您只需将分组更改为"天",然后通过 $sum
"计数"这些条目。
除了不必要的步骤之外,查询本身并没有什么问题。您"匹配"文档,将它们"分组"为"每天唯一ip",然后获得这些唯一匹配的"计数"。
由于您的主要问题似乎是选择日期范围,这里有一个小的PHP代码片段来演示一些事情:
<?php
date_default_timezone_set('UTC');
$dt = new DateTime("2014-02-01", new DateTimeZone('PST'));
echo var_dump( $dt );
echo $dt->getTimestamp(), "'n";
$mongo = new MongoDate( $dt->getTimestamp() );
echo var_dump( $mongo );
echo json_encode( array( $mongo->sec ), "'n";
#echo $mongo->sec, "'n";
$new = new DateTime( date('Y-m-d', $mongo->sec ), new DateTimeZone('PST'));
echo var_dump ($new);
?>
这基本上是一种"去了又回来"的逻辑。但实际上,我是在强制创建一个具有特定时区的新日期。然后,当调用MongoDate时,我们使用getTimetamp()
方法返回自epoch以来的秒数作为构造函数的feeder。根据定义,这总是在UTC中,因此您可以轻松转换。