public function group($p, $cb)
{
if (!isset($p['reduce'])) {
$p['reduce'] = '';
}
$this->_params($p);
$e = explode('.', $p['col'], 2);
$query = ['group' => ['ns' => $e[1], 'key' => $p['key'], '$reduce' => $p['reduce'], 'initial' => $p['initial']]];
if (isset($p[$k = 'cond'])) {
$query['group'][$k] = $p[$k];
}
if (isset($p['rp'])) {
$query['$readPreference'] = $p['rp'];
}
if (isset($p[$k = 'finalize'])) {
if (is_string($p[$k])) {
$p[$k] = new \MongoCode($p[$k]);
}
$query['group'][$k] = $p[$k];
}
if (isset($p[$k = 'keyf'])) {
$query[$k] = $p[$k];
}
if ($this->safeMode) {
static::safeModeEnc($query);
}
$cb = CallbackWrapper::wrap($cb);
try {
$this->request(self::OP_QUERY, pack('V', $p['opts']) . $e[0] . '.$cmd' . "" . pack('VV', $p['offset'], $p['limit']) . bson_encode($query) . (isset($p['fields']) ? bson_encode($p['fields']) : ''), true, null, function ($conn, $reqId = null) use($p, $cb) {
if (!$conn) {
!$cb || $cb(['$err' => 'Connection error.']);
return;
}
$conn->requests[$reqId] = [$p['col'], $cb, false];
});
} catch (\MongoException $e) {
Daemon::log('MongoClient exception: ' . $e->getMessage() . ': ' . $e->getTraceAsString());
if ($cb !== null) {
$cb(['$err' => $e->getMessage(), '$query' => $query, '$fields' => isset($p['fields']) ? $p['fields'] : null]);
}
}
}