Commit 08131477 by Paul Klimov

yii\mongodb\Collection::mapReduce() fixed to handle 'inline' output correctly.

parent 80d69a65
...@@ -521,7 +521,8 @@ class Collection extends Object ...@@ -521,7 +521,8 @@ class Collection extends Object
* and the map values) and does the aggregation. * and the map values) and does the aggregation.
* Argument will be automatically cast to [[\MongoCode]]. * Argument will be automatically cast to [[\MongoCode]].
* @param string|array $out output collection name. It could be a string for simple output * @param string|array $out output collection name. It could be a string for simple output
* ('outputCollection'), or an array for parametrized output (['merge' => 'outputCollection']) * ('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 $condition criteria for including a document in the aggregation.
* @param array $options additional optional parameters to the mapReduce command. Valid options include: * @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. * - sort - array - key to sort the input documents. The sort key must be in an existing index for this collection.
...@@ -530,7 +531,7 @@ class Collection extends Object ...@@ -530,7 +531,7 @@ class Collection extends Object
* - scope - array - specifies global variables that are accessible in the map, reduce and finalize functions. * - 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. * - 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. * - verbose - boolean - specifies whether to include the timing information in the result information.
* @return string the map reduce output collection name. * @return string|array the map reduce output collection name or output results.
* @throws Exception on failure. * @throws Exception on failure.
*/ */
public function mapReduce($map, $reduce, $out, $condition = [], $options = []) public function mapReduce($map, $reduce, $out, $condition = [], $options = [])
...@@ -566,7 +567,7 @@ class Collection extends Object ...@@ -566,7 +567,7 @@ class Collection extends Object
$result = $this->mongoCollection->db->command($command); $result = $this->mongoCollection->db->command($command);
$this->tryResultError($result); $this->tryResultError($result);
Yii::endProfile($token, __METHOD__); Yii::endProfile($token, __METHOD__);
return $result['result']; return array_key_exists('results', $result) ? $result['results'] : $result['result'];
} catch (\Exception $e) { } catch (\Exception $e) {
Yii::endProfile($token, __METHOD__); Yii::endProfile($token, __METHOD__);
throw new Exception($e->getMessage(), (int)$e->getCode(), $e); throw new Exception($e->getMessage(), (int)$e->getCode(), $e);
......
...@@ -240,6 +240,55 @@ class CollectionTest extends MongoDbTestCase ...@@ -240,6 +240,55 @@ class CollectionTest extends MongoDbTestCase
$this->assertEquals($expectedRows, $rows); $this->assertEquals($expectedRows, $rows);
} }
/**
* @depends testMapReduce
*/
public function testMapReduceInline()
{
$collection = $this->getConnection()->getCollection('customer');
$rows = [
[
'name' => 'customer 1',
'status' => 1,
'amount' => 100,
],
[
'name' => 'customer 2',
'status' => 1,
'amount' => 200,
],
[
'name' => 'customer 2',
'status' => 2,
'amount' => 400,
],
[
'name' => 'customer 2',
'status' => 3,
'amount' => 500,
],
];
$collection->batchInsert($rows);
$result = $collection->mapReduce(
'function () {emit(this.status, this.amount)}',
'function (key, values) {return Array.sum(values)}',
['inline' => true],
['status' => ['$lt' => 3]]
);
$expectedRows = [
[
'_id' => 1,
'value' => 300,
],
[
'_id' => 2,
'value' => 400,
],
];
$this->assertEquals($expectedRows, $result);
}
public function testCreateIndex() public function testCreateIndex()
{ {
$collection = $this->getConnection()->getCollection('customer'); $collection = $this->getConnection()->getCollection('customer');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment