/**
* Executes an aggregation framework pipeline on the collection.
*
* Note: this method's return value depends on the MongoDB server version
* and the "useCursor" option. If "useCursor" is true, a Cursor will be
* returned; otherwise, an ArrayIterator is returned, which wraps the
* "result" array from the command response document.
*
* Note: BSON deserialization of inline aggregation results (i.e. not using
* a command cursor) does not yet support a custom type map
* (depends on: https://jira.mongodb.org/browse/PHPC-314).
*
* @see Aggregate::__construct() for supported options
*
* @param array $pipeline List of pipeline operations
* @param array $options Command options
*
* @return Traversable
*/
public function aggregate(array $pipeline, array $options = [])
{
$hasOutStage = Functions::isLastPipelineOperatorOut($pipeline);
/* A "majority" read concern is not compatible with the $out stage, so
* avoid providing the Collection's read concern if it would conflict.
*/
if (!isset($options['readConcern']) && !($hasOutStage && $this->readConcern->getLevel() === ReadConcern::MAJORITY)) {
$options['readConcern'] = $this->readConcern;
}
if (!isset($options['readPreference'])) {
$options['readPreference'] = $this->readPreference;
}
if ($hasOutStage) {
$options['readPreference'] = new ReadPreference(ReadPreference::RP_PRIMARY);
}
if (!isset($options['typeMap']) && (!isset($options['useCursor']) || $options['useCursor'])) {
$options['typeMap'] = $this->typeMap;
}
$operation = new Aggregate($this->databaseName, $this->collectionName, $pipeline, $options);
$server = $this->manager->selectServer($options['readPreference']);
return $operation->execute($server);
}