Skip to content

Instantly share code, notes, and snippets.

@jmikola
Created October 4, 2017 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmikola/86503a9046be269814712c3e35ddd2b0 to your computer and use it in GitHub Desktop.
Save jmikola/86503a9046be269814712c3e35ddd2b0 to your computer and use it in GitHub Desktop.
PHPLIB mapReduce example
<?php
require_once 'vendor/autoload.php';
$client = new MongoDB\Client;
$collection = $client->selectCollection('test', 'mr_example');
$collection->drop();
$collection->insertMany([
['x' => 1, 'y' => 1],
['x' => 1, 'y' => 2],
['x' => 1, 'y' => 3],
['x' => 2, 'y' => 4],
['x' => 2, 'y' => 5],
['x' => 3, 'y' => 6],
]);
// MongoDB\BSON\Javascript supersedes the legacy driver's MongoCode class
$map = new MongoDB\BSON\Javascript('function() { emit(this.x, this.y); }');
$reduce = new MongoDB\BSON\Javascript('function(key, values) { return Array.sum(values); }');
$database = $client->selectDatabase('test');
/* MongoDB\Database::command() always returns a cursor. For commands that return
* a single document (such as mapReduce), we need to iterate on this cursor and
* access the first result to obtain the logical command result.
*
* In the case of commands that return multiple documents via a command cursor,
* (such as aggregate), we could immediately iterate on the returned cursor to
* obtain those results. Internally, MongoDB still returns a single-document
* result, but it only serves as an envelope for constructing a command cursor.
* That is all handled internally by the driver.
*
* @see https://docs.mongodb.com/php-library/current/tutorial/commands/#view-command-results
*/
$cursor = $database->command([
'mapReduce' => 'mr_example',
'map' => $map,
'reduce' => $reduce,
'out' => ['inline' => 1],
]);
$commandResult = $cursor->toArray()[0]);
/* When we dump this value, you'll notice that the command result contains
* instances of BSONDocument and BSONArray, both of which extend PHP's
* ArrayObject class.
*
* By default, the driver converts BSON documents and arrays to PHP stdClass
* objects and arrays, respectively. The library instead uses BSONDocument and
* BSONArray clases for both types. These both differ from the legacy driver,
* where BSON documents and arrays were always converted to PHP arrays.
*
* You can customize the driver and library behavior with a custom type map,
* which can be specified on any of the core library objects (e.g. Client,
* Database, Collection), as an option to Database::command(), or on the
* MongoDB\Driver\Cursor object returned by Database::command().
*
* @see http://php.net/manual/en/mongodb-driver-cursor.settypemap.php
* @see https://docs.mongodb.com/php-library/current/reference/bson/
* @see https://docs.mongodb.com/php-library/current/reference/bson/#emulating-the-legacy-driver
*/
var_dump($commandResult);
$ php example.php
object(MongoDB\Model\BSONDocument)#23 (1) {
["storage":"ArrayObject":private]=>
array(4) {
["results"]=>
object(MongoDB\Model\BSONArray)#21 (1) {
["storage":"ArrayObject":private]=>
array(3) {
[0]=>
object(MongoDB\Model\BSONDocument)#13 (1) {
["storage":"ArrayObject":private]=>
array(2) {
["_id"]=>
float(1)
["value"]=>
float(6)
}
}
[1]=>
object(MongoDB\Model\BSONDocument)#10 (1) {
["storage":"ArrayObject":private]=>
array(2) {
["_id"]=>
float(2)
["value"]=>
float(9)
}
}
[2]=>
object(MongoDB\Model\BSONDocument)#20 (1) {
["storage":"ArrayObject":private]=>
array(2) {
["_id"]=>
float(3)
["value"]=>
float(6)
}
}
}
}
["timeMillis"]=>
int(54)
["counts"]=>
object(MongoDB\Model\BSONDocument)#22 (1) {
["storage":"ArrayObject":private]=>
array(4) {
["input"]=>
int(6)
["emit"]=>
int(6)
["reduce"]=>
int(2)
["output"]=>
int(3)
}
}
["ok"]=>
float(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment