Example #1
0
 /**
  * Performs aggregation using Mongo "map reduce" mechanism.
  * Note: this function will not return the aggregation result, instead it will
  * write it inside the another Mongo collection specified by "out" parameter.
  * For example:
  *
  * ~~~
  * $customerCollection = Yii::$app->mongo->getCollection('customer');
  * $resultCollectionName = $customerCollection->mapReduce(
  *     'function () {emit(this.status, this.amount)}',
  *     'function (key, values) {return Array.sum(values)}',
  *     'mapReduceOut',
  *     ['status' => 3]
  * );
  * $query = new Query();
  * $results = $query->from($resultCollectionName)->all();
  * ~~~
  *
  * @param \MongoCode|string $map function, which emits map data from collection.
  * Argument will be automatically cast to [[\MongoCode]].
  * @param \MongoCode|string $reduce function that takes two arguments (the map key
  * and the map values) and does the aggregation.
  * Argument will be automatically cast to [[\MongoCode]].
  * @param string|array $out output collection name. It could be a string for simple output
  * ('outputCollection'), or an array for parametrized output (['merge' => 'outputCollection']).
  * You can pass ['inline' => true] to fetch the result at once without temporary collection usage.
  * @param array $condition criteria for including a document in the aggregation.
  * @param array $options additional optional parameters to the mapReduce command. Valid options include:
  *  - sort - array - key to sort the input documents. The sort key must be in an existing index for this collection.
  *  - limit - the maximum number of documents to return in the collection.
  *  - finalize - function, which follows the reduce method and modifies the output.
  *  - scope - array - specifies global variables that are accessible in the map, reduce and finalize functions.
  *  - jsMode - boolean -Specifies whether to convert intermediate data into BSON format between the execution of the map and reduce functions.
  *  - verbose - boolean - specifies whether to include the timing information in the result information.
  * @return string|array the map reduce output collection name or output results.
  * @throws Exception on failure.
  */
 public function mapReduce($map, $reduce, $out, $condition = [], $options = [])
 {
     $command = ['mapReduce' => $this->getName(), 'map' => $map, 'reduce' => $reduce, 'out' => $out];
     if (!empty($condition)) {
         $command['query'] = $this->buildCondition($condition);
     }
     $command = new \MongoDB\Driver\Command(array_merge($command, $options));
     $token = $this->composeLogToken('mapReduce', [$map, $reduce, $out]);
     Yii::info($token, __METHOD__);
     try {
         Yii::beginProfile($token, __METHOD__);
         $result = $this->mongoManager->executeCommand($this->dbName, $command);
         $this->tryResultError($result);
         Yii::endProfile($token, __METHOD__);
         $row = MongoHelper::cursorFirst($result);
         return isset($row['result']) ? $row['result'] : $row['results'];
     } catch (\Exception $e) {
         Yii::endProfile($token, __METHOD__);
         throw new Exception($e->getMessage(), (int) $e->getCode(), $e);
     }
 }
Example #2
0
 /**
  * Executes Mongo command.
  * @param array $command command specification.
  * @param array $options options in format: "name" => "value"
  * @return array database response.
  * @throws Exception on failure.
  */
 public function executeCommand($command, $options = [])
 {
     $token = $this->getName() . '.$cmd(' . Json::encode($command) . ', ' . Json::encode($options) . ')';
     Yii::info($token, __METHOD__);
     try {
         Yii::beginProfile($token, __METHOD__);
         $command = new \MongoDB\Driver\Command($command);
         $result = $this->mongoManager->executeCommand($this->dbName, $command);
         $this->tryResultError($result);
         Yii::endProfile($token, __METHOD__);
         return MongoHelper::cursorFirst($result);
     } catch (\Exception $e) {
         Yii::endProfile($token, __METHOD__);
         throw new Exception($e->getMessage(), (int) $e->getCode(), $e);
     }
 }
Example #3
0
 /**
  * @param \MongoDB\Driver\Cursor $cursor Mongo cursor instance to fetch data from.
  * @param boolean $all whether to fetch all rows or only first one.
  * @param string|callable $indexBy value to index by.
  * @return array|boolean result.
  * @see Query::fetchRows()
  */
 protected function fetchRowsInternal($cursor, $all, $indexBy)
 {
     if ($all) {
         $rows = [];
         foreach ($cursor as $row) {
             $rows[] = MongoHelper::resultToArray($row);
         }
         return $rows;
     } else {
         foreach ($cursor as $row) {
             break;
         }
         return isset($row) ? MongoHelper::resultToArray($row) : false;
     }
 }