public function execute()
{
$options = $this->options;
switch ($this->query['type']) {
case self::TYPE_FIND:
$cursor = $this->collection->find($this->query['query'], isset($this->query['select']) ? $this->query['select'] : []);
return $this->prepareCursor($cursor);
case self::TYPE_FIND_AND_UPDATE:
$queryOptions = $this->getQueryOptions('new', 'select', 'sort', 'upsert');
$queryOptions = $this->renameQueryOptions($queryOptions, ['select' => 'fields']);
return $this->collection->findAndUpdate($this->query['query'], $this->query['newObj'], array_merge($options, $queryOptions));
case self::TYPE_FIND_AND_REMOVE:
$queryOptions = $this->getQueryOptions('select', 'sort');
$queryOptions = $this->renameQueryOptions($queryOptions, ['select' => 'fields']);
return $this->collection->findAndRemove($this->query['query'], array_merge($options, $queryOptions));
case self::TYPE_INSERT:
return $this->collection->insert($this->query['newObj'], $options);
case self::TYPE_UPDATE:
return $this->collection->update($this->query['query'], $this->query['newObj'], array_merge($options, $this->getQueryOptions('multiple', 'upsert')));
case self::TYPE_REMOVE:
return $this->collection->remove($this->query['query'], $options);
case self::TYPE_GROUP:
if (!empty($this->query['query'])) {
$options['cond'] = $this->query['query'];
}
$collection = $this->collection;
$query = $this->query;
$closure = function () use($collection, $query, $options) {
return $collection->group($query['group']['keys'], $query['group']['initial'], $query['group']['reduce'], array_merge($options, $query['group']['options']));
};
return $this->withReadPreference($collection->getDatabase(), $closure);
case self::TYPE_MAP_REDUCE:
if (isset($this->query['limit'])) {
$options['limit'] = $this->query['limit'];
}
$collection = $this->collection;
$query = $this->query;
$closure = function () use($collection, $query, $options) {
return $collection->mapReduce($query['mapReduce']['map'], $query['mapReduce']['reduce'], $query['mapReduce']['out'], $query['query'], array_merge($options, $query['mapReduce']['options']));
};
$results = $this->withReadPreference($collection->getDatabase(), $closure);
return $results instanceof Cursor ? $this->prepareCursor($results) : $results;
case self::TYPE_DISTINCT:
$collection = $this->collection;
$query = $this->query;
$closure = function () use($collection, $query, $options) {
return $collection->distinct($query['distinct'], $query['query'], $options);
};
return $this->withReadPreference($collection->getDatabase(), $closure);
case self::TYPE_GEO_NEAR:
if (isset($this->query['limit'])) {
$options['num'] = $this->query['limit'];
}
$collection = $this->collection;
$query = $this->query;
$closure = function () use($collection, $query, $options) {
return $collection->near($query['geoNear']['near'], $query['query'], array_merge($options, $query['geoNear']['options']));
};
return $this->withReadPreference($collection->getDatabase(), $closure);
case self::TYPE_COUNT:
$collection = $this->collection;
$query = $this->query;
$closure = function () use($collection, $query, $options) {
return $collection->count($query['query'], array_merge($options, $this->getQueryOptions('hint', 'limit', 'maxTimeMS', 'skip')));
};
return $this->withReadPreference($collection, $closure);
}
}