У кого-нибудь есть хороший способ запустить групповую функцию на PHP с подсчетом DISTINCT? Ситуация такова: я хочу проверить уникальные логины для нашего приложения. Вот как выглядит документ в текущей коллекции, который я запрашиваю:
Array ( [_id] => MongoId Object ( [$id] => 50f6da87686ba9f449000003 ) [userId] => 50f6bd0f686ba91a4000000f [action] => login [time] => 1358355079
То, что я хотел бы сделать, – подсчитать UNIQUE userIDs через отчет группы по дате. Это оператор группы, который я использую (в PHP):
$map= new MongoCode('function(frequency) { var date = new Date(Number(frequency.time) * 1000 - (8 * 3600000)); var dd = date.getDate(); var yyyy = date.getFullYear(); var mm = date.getMonth() + 1; if(dd<10){dd="0"+dd} if(mm<10){mm="0"+mm} var transday = yyyy + "-"+ mm + "-" + dd; return{"date": transday} }'); $initial = array('logins' => array()); $reduce = "function(obj, prev){ prev.logins.push(obj.userId); }"; try{ $distinct = array(); $g = $this->_bingomongo->selectCollection("UserLog")->group($map, $initial, $reduce);
С этого момента я просто делаю array_unique
в памяти … но то, что я действительно хотел бы сделать (и не могу найти хороший ответ в сети), выполняется отдельным счетом в группе. Я видел пару других примеров, где мы можем использовать array(distinct=>'key')
но я хочу сделать счет. Есть предположения?
Вот остальная часть кода в текущем (несовершенном) формате:
foreach($g['retval'] as $k=>$v) { $distinct[date('m.d', strtotime($v['date']))] = array_unique($v['logins']); } } catch(Exception $e) { return $e; } return $g;
С удовольствием сделаем это на карте / уменьшим, если это необходимо, но скорее найдем способ сохранить его в группе (как COUNT (отлично)).
Вы должны сделать что-то вроде этого:
... $initial = array('logins' => array()); $reduce = "function(obj, prev){ prev.logins[obj.userId] = 1; }"; $finalize = "function(result) { result.loginList = Object.keys(result.logins); result.count = result.loginList.length; }"; try{ $distinct = array(); $g = $this->_bingomongo->selectCollection("UserLog")->group( $map, $initial, $reduce, array('finalize'=>$finalize));