Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongo-php-library
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sinan
mongo-php-library
Commits
0985dfa8
Commit
0985dfa8
authored
Aug 08, 2017
by
Jeremy Mikola
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PHPLIB-53: Create mapReduce command helper
parent
c1f6e23d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
659 additions
and
0 deletions
+659
-0
MapReduceResult.php
src/MapReduceResult.php
+99
-0
MapReduce.php
src/Operation/MapReduce.php
+318
-0
MapReduceFunctionalTest.php
tests/Operation/MapReduceFunctionalTest.php
+133
-0
MapReduceTest.php
tests/Operation/MapReduceTest.php
+109
-0
No files found.
src/MapReduceResult.php
0 → 100644
View file @
0985dfa8
<?php
/*
* Copyright 2017 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace
MongoDB
;
use
IteratorAggregate
;
use
stdClass
;
/**
* Result class for mapReduce command results.
*
* This class allows for iteration of mapReduce results irrespective of the
* output method (e.g. inline, collection) via the IteratorAggregate interface.
* It also provides access to command statistics.
*
* @api
* @see \MongoDB\Collection::mapReduce()
* @see https://docs.mongodb.com/manual/reference/command/mapReduce/
*/
class
MapReduceResult
implements
IteratorAggregate
{
private
$getIterator
;
private
$executionTimeMS
;
private
$counts
;
private
$timing
;
/**
* Constructor.
*
* @internal
* @param callable $getIterator Callback that returns a Traversable for mapReduce results
* @param stdClass $result Result document from the mapReduce command
*/
public
function
__construct
(
callable
$getIterator
,
stdClass
$result
)
{
$this
->
getIterator
=
$getIterator
;
$this
->
executionTimeMS
=
(
integer
)
$result
->
timeMillis
;
$this
->
counts
=
(
array
)
$result
->
counts
;
$this
->
timing
=
isset
(
$result
->
timing
)
?
(
array
)
$result
->
timing
:
[];
}
/**
* Returns various count statistics from the mapReduce command.
*
* @return array
*/
public
function
getCounts
()
{
return
$this
->
counts
;
}
/**
* Return the command execution time in milliseconds.
*
* @return integer
*/
public
function
getExecutionTimeMS
()
{
return
$this
->
executionTimeMS
;
}
/**
* Return the mapReduce results as a Traversable.
*
* @see http://php.net/iteratoraggregate.getiterator
* @return Traversable
*/
public
function
getIterator
()
{
return
call_user_func
(
$this
->
getIterator
);
}
/**
* Returns various timing statistics from the mapReduce command.
*
* Note: timing statistics are only available if the mapReduce command's
* "verbose" option was true; otherwise, an empty array will be returned.
*
* @return array
*/
public
function
getTiming
()
{
return
$this
->
timing
;
}
}
src/Operation/MapReduce.php
0 → 100644
View file @
0985dfa8
This diff is collapsed.
Click to expand it.
tests/Operation/MapReduceFunctionalTest.php
0 → 100644
View file @
0985dfa8
<?php
namespace
MongoDB\Tests\Operation
;
use
MongoDB\BSON\Javascript
;
use
MongoDB\Driver\BulkWrite
;
use
MongoDB\Operation\Find
;
use
MongoDB\Operation\MapReduce
;
class
MapReduceFunctionalTest
extends
FunctionalTestCase
{
public
function
testResult
()
{
$this
->
createFixtures
(
3
);
$map
=
new
Javascript
(
'function() { emit(this.x, this.y); }'
);
$reduce
=
new
Javascript
(
'function(key, values) { return Array.sum(values); }'
);
$out
=
[
'inline'
=>
1
];
$operation
=
new
MapReduce
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
(),
$map
,
$reduce
,
$out
);
$result
=
$operation
->
execute
(
$this
->
getPrimaryServer
());
$this
->
assertInstanceOf
(
'MongoDB\MapReduceResult'
,
$result
);
$this
->
assertGreaterThanOrEqual
(
0
,
$result
->
getExecutionTimeMS
());
$this
->
assertNotEmpty
(
$result
->
getCounts
());
$this
->
assertNotEmpty
(
$result
->
getTiming
());
}
public
function
testResultDoesNotIncludeTimingWithoutVerboseOption
()
{
$this
->
createFixtures
(
3
);
$map
=
new
Javascript
(
'function() { emit(this.x, this.y); }'
);
$reduce
=
new
Javascript
(
'function(key, values) { return Array.sum(values); }'
);
$out
=
[
'inline'
=>
1
];
$operation
=
new
MapReduce
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
(),
$map
,
$reduce
,
$out
,
[
'verbose'
=>
false
]);
$result
=
$operation
->
execute
(
$this
->
getPrimaryServer
());
$this
->
assertInstanceOf
(
'MongoDB\MapReduceResult'
,
$result
);
$this
->
assertGreaterThanOrEqual
(
0
,
$result
->
getExecutionTimeMS
());
$this
->
assertNotEmpty
(
$result
->
getCounts
());
$this
->
assertEmpty
(
$result
->
getTiming
());
}
/**
* @dataProvider provideTypeMapOptionsAndExpectedDocuments
*/
public
function
testTypeMapOptionWithInlineResults
(
array
$typeMap
=
null
,
array
$expectedDocuments
)
{
$this
->
createFixtures
(
3
);
$map
=
new
Javascript
(
'function() { emit(this.x, this.y); }'
);
$reduce
=
new
Javascript
(
'function(key, values) { return Array.sum(values); }'
);
$out
=
[
'inline'
=>
1
];
$operation
=
new
MapReduce
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
(),
$map
,
$reduce
,
$out
,
[
'typeMap'
=>
$typeMap
]);
$results
=
iterator_to_array
(
$operation
->
execute
(
$this
->
getPrimaryServer
()));
$this
->
assertEquals
(
$expectedDocuments
,
$results
);
}
public
function
provideTypeMapOptionsAndExpectedDocuments
()
{
return
[
[
null
,
[
(
object
)
[
'_id'
=>
1
,
'value'
=>
3
],
(
object
)
[
'_id'
=>
2
,
'value'
=>
6
],
(
object
)
[
'_id'
=>
3
,
'value'
=>
9
],
],
],
[
[
'root'
=>
'array'
],
[
[
'_id'
=>
1
,
'value'
=>
3
],
[
'_id'
=>
2
,
'value'
=>
6
],
[
'_id'
=>
3
,
'value'
=>
9
],
],
],
[
[
'root'
=>
'object'
],
[
(
object
)
[
'_id'
=>
1
,
'value'
=>
3
],
(
object
)
[
'_id'
=>
2
,
'value'
=>
6
],
(
object
)
[
'_id'
=>
3
,
'value'
=>
9
],
],
],
];
}
/**
* @dataProvider provideTypeMapOptionsAndExpectedDocuments
*/
public
function
testTypeMapOptionWithOutputCollection
(
array
$typeMap
=
null
,
array
$expectedDocuments
)
{
$this
->
createFixtures
(
3
);
$map
=
new
Javascript
(
'function() { emit(this.x, this.y); }'
);
$reduce
=
new
Javascript
(
'function(key, values) { return Array.sum(values); }'
);
$out
=
$this
->
getCollectionName
()
.
'.output'
;
$operation
=
new
MapReduce
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
(),
$map
,
$reduce
,
$out
,
[
'typeMap'
=>
$typeMap
]);
$results
=
iterator_to_array
(
$operation
->
execute
(
$this
->
getPrimaryServer
()));
$this
->
assertEquals
(
$expectedDocuments
,
$results
);
$operation
=
new
Find
(
$this
->
getDatabaseName
(),
$out
,
[],
[
'typeMap'
=>
$typeMap
]);
$cursor
=
$operation
->
execute
(
$this
->
getPrimaryServer
());
$this
->
assertEquals
(
$expectedDocuments
,
iterator_to_array
(
$cursor
));
}
/**
* Create data fixtures.
*
* @param integer $n
*/
private
function
createFixtures
(
$n
)
{
$bulkWrite
=
new
BulkWrite
([
'ordered'
=>
true
]);
for
(
$i
=
1
;
$i
<=
$n
;
$i
++
)
{
$bulkWrite
->
insert
([
'x'
=>
$i
,
'y'
=>
$i
]);
$bulkWrite
->
insert
([
'x'
=>
$i
,
'y'
=>
$i
*
2
]);
}
$result
=
$this
->
manager
->
executeBulkWrite
(
$this
->
getNamespace
(),
$bulkWrite
);
$this
->
assertEquals
(
$n
*
2
,
$result
->
getInsertedCount
());
}
}
tests/Operation/MapReduceTest.php
0 → 100644
View file @
0985dfa8
<?php
namespace
MongoDB\Tests\Operation
;
use
MongoDB\BSON\Javascript
;
use
MongoDB\BSON\ObjectID
;
use
MongoDB\Operation\MapReduce
;
use
stdClass
;
class
MapReduceTest
extends
TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @dataProvider provideInvalidOutValues
*/
public
function
testConstructorOutArgumentTypeCheck
(
$out
)
{
$map
=
new
Javascript
(
'function() { emit(this.x, this.y); }'
);
$reduce
=
new
Javascript
(
'function(key, values) { return Array.sum(values); }'
);
new
MapReduce
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
(),
$map
,
$reduce
,
$out
);
}
public
function
provideInvalidOutValues
()
{
return
$this
->
wrapValuesForDataProvider
([
123
,
3.14
,
true
]);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @dataProvider provideInvalidConstructorOptions
*/
public
function
testConstructorOptionTypeChecks
(
array
$options
)
{
$map
=
new
Javascript
(
'function() { emit(this.x, this.y); }'
);
$reduce
=
new
Javascript
(
'function(key, values) { return Array.sum(values); }'
);
$out
=
[
'inline'
=>
1
];
new
MapReduce
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
(),
$map
,
$reduce
,
$out
,
$options
);
}
public
function
provideInvalidConstructorOptions
()
{
$options
=
[];
foreach
(
$this
->
getInvalidBooleanValues
()
as
$value
)
{
$options
[][]
=
[
'bypassDocumentValidation'
=>
$value
];
}
foreach
(
$this
->
getInvalidDocumentValues
()
as
$value
)
{
$options
[][]
=
[
'collation'
=>
$value
];
}
foreach
(
$this
->
getInvalidJavascriptValues
()
as
$value
)
{
$options
[][]
=
[
'finalize'
=>
$value
];
}
foreach
(
$this
->
getInvalidBooleanValues
()
as
$value
)
{
$options
[][]
=
[
'jsMode'
=>
$value
];
}
foreach
(
$this
->
getInvalidIntegerValues
()
as
$value
)
{
$options
[][]
=
[
'limit'
=>
$value
];
}
foreach
(
$this
->
getInvalidIntegerValues
()
as
$value
)
{
$options
[][]
=
[
'maxTimeMS'
=>
$value
];
}
foreach
(
$this
->
getInvalidDocumentValues
()
as
$value
)
{
$options
[][]
=
[
'query'
=>
$value
];
}
foreach
(
$this
->
getInvalidReadConcernValues
()
as
$value
)
{
$options
[][]
=
[
'readConcern'
=>
$value
];
}
foreach
(
$this
->
getInvalidReadPreferenceValues
()
as
$value
)
{
$options
[][]
=
[
'readPreference'
=>
$value
];
}
foreach
(
$this
->
getInvalidDocumentValues
()
as
$value
)
{
$options
[][]
=
[
'scope'
=>
$value
];
}
foreach
(
$this
->
getInvalidDocumentValues
()
as
$value
)
{
$options
[][]
=
[
'sort'
=>
$value
];
}
foreach
(
$this
->
getInvalidArrayValues
()
as
$value
)
{
$options
[][]
=
[
'typeMap'
=>
$value
];
}
foreach
(
$this
->
getInvalidBooleanValues
()
as
$value
)
{
$options
[][]
=
[
'verbose'
=>
$value
];
}
foreach
(
$this
->
getInvalidWriteConcernValues
()
as
$value
)
{
$options
[][]
=
[
'writeConcern'
=>
$value
];
}
return
$options
;
}
private
function
getInvalidJavascriptValues
()
{
return
[
123
,
3.14
,
'foo'
,
true
,
[],
new
stdClass
,
new
ObjectID
];
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment