Commit 749f0aa0 authored by Jeremy Mikola's avatar Jeremy Mikola

Merge pull request #144

parents c31e5300 6ece2bcf
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# BSON Conversion
## Deserialization
By default, the library returns BSON documents and arrays as
MongoDB\Model\BSONDocument and MongoDB\Model\BSONArray objects, respectively.
Both of those classes extend PHP's [ArrayObject][arrayobject] class and
implement the driver's [MongoDB\BSON\Serializable][serializable] and
[MongoDB\BSON\Unserializable][unserializable] interfaces.
[arrayobject]: http://php.net/arrayobject
[serializable]: http://php.net/mongodb-bson-serializable
[unserializable]: http://php.net/mongodb-bson-unserializable
## Type Maps
Most methods that read data from MongoDB support a "typeMap" option, which
allows control over how BSON is converted to PHP. Additionally, the
[MongoDB\Client][client], [MongoDB\Database][database], and
[MongoDB\Collection][collection] classes accept a "typeMap" option, which will
apply to any supporting methods and selected classes by default.
[client]: ../classes/client.md
[database]: ../classes/database.md
[collection]: ../classes/collection.md
The [MongoDB\Client][client], [MongoDB\Database][database], and
[MongoDB\Collection][collection] classes use the following type map by default:
```php
[
'array' => 'MongoDB\Model\BSONArray',
'document' => 'MongoDB\Model\BSONDocument',
'root' => 'MongoDB\Model\BSONDocument',
]
```
## Persistable Classes
Classes implementing [MongoDB\BSON\Persistable][persistable] will be serialized
and deserialized according to the [Persistence][persistence] specification. This
behavior occurs by default in the [driver][ext-mongodb] and does not require use
of the "typeMap" option.
[persistable]: http://php.net/mongodb-bson-persistable
[persistence]: http://php.net/manual/en/mongodb.persistence.php
[ext-mongodb]: https://php.net/mongodb
Given the following class definition:
```
<?php
class Person implements MongoDB\BSON\Persistable
{
private $id;
private $name;
private $createdAt;
public function __construct($name)
{
$this->id = new MongoDB\BSON\ObjectID;
$this->name = (string) $name;
// Get current time in milliseconds since the epoch
$msec = floor(microtime(true) * 1000);
$this->createdAt = new MongoDB\BSON\UTCDateTime($msec);
}
function bsonSerialize()
{
return [
'_id' => $this->id,
'name' => $this->name,
'createdAt' => $this->createdAt,
];
}
function bsonUnserialize(array $data)
{
$this->id = $data['_id'];
$this->name = $data['name'];
$this->createdAt = $data['createdAt'];
}
}
```
The following example constructs a Person object, inserts it into the database,
and reads it back as an object of the same type (without the use of the
"typeMap" option):
```
<?php
$collection = (new MongoDB\Client)->demo->persons;
$result = $collection->insertOne(new Person('Bob'));
$person = $collection->findOne(['_id' => $result->getInsertedId()]);
var_dump($person);
```
The above example would output something similar to:
```
object(Person)#18 (3) {
["id":"Person":private]=>
object(MongoDB\BSON\ObjectID)#15 (1) {
["oid"]=>
string(24) "56fad2c36118fd2e9820cfc1"
}
["name":"Person":private]=>
string(3) "Bob"
["createdAt":"Person":private]=>
object(MongoDB\BSON\UTCDateTime)#17 (1) {
["milliseconds"]=>
int(1459278531218)
}
}
```
The same document in the MongoDB shell might display as:
```
> db.persons.findOne()
{
"_id" : ObjectId("56fad2c36118fd2e9820cfc1"),
"__pclass" : BinData(128,"UGVyc29u"),
"name" : "Bob",
"createdAt" : ISODate("2016-03-29T19:08:51.218Z")
}
```
**Note:** [MongoDB\BSON\Persistable][persistable] may only be used for root and
embedded BSON documents; BSON arrays are not supported.
## Emulating the Legacy Driver
The legacy [mongo extension][ext-mongo] returned both BSON documents and
arrays as PHP arrays. While PHP arrays are convenient to work with, this
behavior was problematic for several reasons:
[ext-mongo]: http://php.net/mongo
* Different BSON types could deserialize to the same PHP value (e.g.
`{"0": "foo"}` and `["foo"]`), which made it impossible to infer the
original BSON type.
* Numerically indexed PHP arrays would be serialized as BSON documents if there
was a gap in their key sequence. Such gaps were easily (and inadvertently)
caused by unsetting a key to remove an element and forgetting to reindex the
array.
The libary's MongoDB\Model\BSONDocument and MongoDB\Model\BSONArray classes
address these concerns by preserving the BSON type information during
serialization and deserialization; however, some users may still prefer the
legacy behavior. If desired, the following "typeMap" option can be used to have
the library return everything as a PHP array:
```
<?php
$client = new MongoDB\Client(
null,
[],
['typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']]
);
$document = $client->demo->zips->findOne(
['_id' => '94301'],
['typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']]
);
var_dump($document);
```
The above example would output something similar to:
```
array(5) {
["_id"]=>
string(5) "94301"
["city"]=>
string(9) "PALO ALTO"
["loc"]=>
array(2) {
[0]=>
float(-122.149685)
[1]=>
float(37.444324)
}
["pop"]=>
int(15965)
["state"]=>
string(2) "CA"
}
```
# Database Commands
While the library provides helpers for some common database commands, it is far
from an [exhaustive list][command-list]. This page will demonstrate how to
execute arbitrary commands on the MongoDB server via the
[Database::command()][command] method and access their results.
[command-list]: https://docs.mongodb.org/manual/reference/command/
[command]: ../classes/database.md#command
## Single Result Documents
The [command()][command] method always returns a
[MongoDB\Driver\Cursor][cursor]. Unless otherwise stated in the MongoDB
documentation, command responses are returned as a single document. Reading such
a result will require iterating on the cursor and accessing the first (and only)
document, like so:
[cursor]: http://php.net/mongodb-driver-cursor
```
<?php
$database = (new MongoDB\Client)->demo;
$cursor = $database->command(['ping' => 1]);
var_dump($cursor->toArray()[0]);
```
The above example would output something similar to:
```
object(MongoDB\Model\BSONDocument)#2 (1) {
["storage":"ArrayObject":private]=>
array(1) {
["ok"]=>
float(1)
}
}
```
## Iterable Results as a Command Cursor
Some commands, such as [listCollections][listcollections], return their results
via an iterable command cursor. In this case, the returned
[MongoDB\Driver\Cursor][cursor] may be iterated in the same manner as one might
do with a [Collection::find()][find] query, like so:
[listcollections]: http://docs.mongodb.org/manual/reference/command/listCollections/
[find]: ../classes/collection.md#find
```
<?php
$database = (new MongoDB\Client)->demo;
$cursor = $database->command(['listCollections' => 1]);
foreach ($cursor as $collection) {
echo $collection['name'], "\n";
}
```
The above example would output something similar to:
```
persons
posts
zips
```
**Note:** at the protocol level, commands that support a cursor actually return
a single result document with the essential ingredients for constructing the
command cursor (i.e. the cursor's ID, namespace, and first batch of results);
however, the driver's [executeCommand()][executecommand] method already detects
such a result and constructs the iterable command cursor for us.
[executecommand]: http://php.net/manual/en/mongodb-driver-manager.executecommand.php
## Specifying a Read Preference
Some commands, such as [createUser][createUser], can only be executed on a
primary server. Command helpers in the library, such as
[Database::drop()][drop], know to apply their own read preference if necessary;
however, [command()][command] is a generic method and has no special knowledge.
It defaults to the read preference of the Database object on which it is
invoked. In such cases, it can be helpful to explicitly specify the correct read
preference, like so:
[createUser]: https://docs.mongodb.org/manual/reference/command/createUser/
[drop]: ../classes/database.md#drop
```
<?php
$db = (new MongoDB\Client)->demo;
$cursor = $db->command(
[
'createUser' => 'username',
'pwd' => 'password',
'roles' => ['readWrite'],
],
[
'readPreference' => new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY),
]
);
var_dump($cursor->toArray()[0]);
```
The above example would output something similar to:
```
object(MongoDB\Model\BSONDocument)#8 (1) {
["storage":"ArrayObject":private]=>
array(1) {
["ok"]=>
float(1)
}
}
```
# CRUD Operations
CRUD is an acronym for Create, Read, Update, and Delete. These operations may be
performed via the [MongoDB\Collection][collection] class, which implements
MongoDB's cross-driver [CRUD specification][crud-spec]. This page will
demonstrate how to insert, query, update, and delete documents using the
library. A general introduction to CRUD operations in MongoDB may be found in
the [MongoDB Manual][crud].
[collection]: ../classes/collection.md
[crud-spec]: https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst
[crud]: https://docs.mongodb.org/manual/crud/
## Finding One Document
The [findOne()][findone] method returns the first matched document, or null if
no document was matched.
[findone]: ../classes/collection.md#findone
```
<?php
$collection = (new MongoDB\Client)->demo->zips;
$document = $collection->findOne(['_id' => '94301']);
var_dump($document);
```
The above example would output something similar to:
```
object(MongoDB\Model\BSONDocument)#13 (1) {
["storage":"ArrayObject":private]=>
array(5) {
["_id"]=>
string(5) "94301"
["city"]=>
string(9) "PALO ALTO"
["loc"]=>
object(MongoDB\Model\BSONArray)#12 (1) {
["storage":"ArrayObject":private]=>
array(2) {
[0]=>
float(-122.149685)
[1]=>
float(37.444324)
}
}
["pop"]=>
int(15965)
["state"]=>
string(2) "CA"
}
}
```
## Finding Many Documents
The [find()][find] method returns a [MongoDB\Driver\Cursor][cursor] object,
which may be iterated upon to access all matched documents. The following
example queries for all zip codes in a given city:
[find]: ../classes/collection.md#find
[cursor]: http://php.net/mongodb-driver-cursor
```
<?php
$collection = (new MongoDB\Client)->demo->zips;
$cursor = $collection->find(['city' => 'JERSEY CITY', 'state' => 'NJ']);
foreach ($cursor as $document) {
echo $document['_id'], "\n";
}
```
The above example would output something similar to:
```
07302
07304
07305
07306
07307
07310
```
## Query Projection
Queries may include a [projection][projection] to include or exclude specific
fields in the returned documents. The following example selects only the
population field for the zip code:
[projection]: https://docs.mongodb.org/manual/tutorial/project-fields-from-query-results/
```
<?php
$collection = (new MongoDB\Client)->demo->zips;
$document = $collection->findOne(
['_id' => '10011'],
['projection' => ['pop => 1']]
);
var_dump($document);
```
The above example would output something similar to:
```
object(MongoDB\Model\BSONDocument)#12 (1) {
["storage":"ArrayObject":private]=>
array(2) {
["_id"]=>
string(5) "10011"
["pop"]=>
int(46560)
}
}
```
**Note:** the "_id" field is included by default unless explicitly excluded.
## Limit, Sort, and Skip Options
In addition to criteria, queries may take options to limit, sort, and skip
returned documents. The following example queries for the five most populous
zip codes in the United States:
```
<?php
$collection = (new MongoDB\Client)->demo->zips;
$cursor = $collection->find(
[],
[
'limit' => 5,
'sort' => ['pop' => -1],
]
);
foreach ($cursor as $document) {
echo $document['_id'], "\n";
}
```
The above example would output something similar to:
```
60623: CHICAGO, IL
11226: BROOKLYN, NY
10021: NEW YORK, NY
10025: NEW YORK, NY
90201: BELL GARDENS, CA
```
## Aggregation
The [Aggregation Framework][aggregation] may be used to issue complex queries
that filter, transform, and group collection data. The [aggregate()][aggregate]
method returns a [Traversable][traversable] object, which may be iterated
upon to access the results of an aggregation pipeline.
[aggregation]: https://docs.mongodb.org/manual/core/aggregation-pipeline/
[aggregate]: ../classes/collection.md#aggregate
[traversable]: http://php.net/traversable
```
<?php
$collection = (new MongoDB\Client)->demo->zips;
$cursor = $collection->aggregate([
['$group' => ['_id' => '$state', 'count' => ['$sum' => 1]]],
['$sort' => ['count' => -1]],
['$limit' => 5],
]);
foreach ($cursor as $state) {
printf("%s has %d zip codes\n", $state['_id'], $state['count']);
}
```
The above example would output something similar to:
```
TX has 1671 zip codes
NY has 1595 zip codes
CA has 1516 zip codes
PA has 1458 zip codes
IL has 1237 zip codes
```
**Note:** [aggregate()][aggregate] is documented as returning a
[Traversable][traversable] object because the [aggregate][aggregate-cmd] command
may return its results inline (i.e. a single result document's array field,
which the library will package as a PHP iterator) or via a command cursor (i.e.
[MongoDB\Driver\Cursor][cursor]).
[aggregate-cmd]: (http://docs.mongodb.org/manual/reference/command/aggregate/)
# Example Data
Some examples in this documentation use example data fixtures from
[zips.json](http://media.mongodb.org/zips.json). This is a dataset comprised of
United States postal codes, populations, and geographic locations.
[zips.json][zips]. This is a dataset comprised of United States postal codes,
populations, and geographic locations.
Importing the dataset into MongoDB can be done in several ways. The following
example uses [PHP driver](http://php.net/mongodb) (i.e. `mongodb` extension).
example uses [mongodb extension][ext-mongodb]:
[zips]: http://media.mongodb.org/zips.json
[ext-mongodb]: http://php.net/mongodb
```
<?php
$file = 'http://media.mongodb.org/zips.json';
$zips = file($file, FILE_IGNORE_NEW_LINES);
......@@ -30,10 +35,11 @@ Executing this script should yield the following output:
Inserted 29353 documents
```
You may also import the dataset using the
[`mongoimport`](http://docs.mongodb.org/manual/reference/program/mongoimport/)
command, which is included with MongoDB:
You may also import the dataset using the [mongoimport][mongoimport] command,
which is included with MongoDB:
```
[mongoimport]: http://docs.mongodb.org/manual/reference/program/mongoimport/
```bash
$ mongoimport --db demo --collection zips --file zips.json --drop
```
# Indexes
Indexes may be managed via the [MongoDB\Collection][collection] class, which
implements MongoDB's cross-driver [Index Management][index-spec] and
[Enumerating Indexes][enum-spec] specifications. This page will demonstrate how
to create, list, and drop indexes using the library. General information on how
indexes work in MongoDB may be found in the [MongoDB manual][indexes].
[collection]: ../classes/collection.md
[index-spec]: https://github.com/mongodb/specifications/blob/master/source/index-management.rst
[enum-spec]: https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst
[indexes]: https://docs.mongodb.org/manual/indexes/
## Creating Indexes
Indexes may be created via the [createIndex()][createindex] and
[createIndexes()][createindexes] methods. The following example creates an
ascending index on the "state" field:
[createindex]: ../classes/collection.md#createindex
[createindexes]: ../classes/collection.md#createindexes
```
<?php
$collection = (new MongoDB\Client)->demo->zips;
$result = $collection->createIndex(['state' => 1]);
var_dump($result);
```
Creating an index will return its name, which is automatically generated from
its specification (i.e. fields and orderings). The above example would output
something similar to:
```
string(7) "state_1"
```
### Enumerating Indexes
Information about indexes in a collection may be obtained via the
[listIndexes()][listindexes] method, which returns an iterator of
MongoDB\Model\IndexInfo objects. The following example lists all indexes in the
"demo.zips" collection:
[listindexes]: ../classes/collection.md#listindexes
```
<?php
$collection = (new MongoDB\Client)->demo->zips;
foreach ($collection->listIndexes() as $indexInfo) {
var_dump($indexInfo);
}
```
The above example would output something similar to:
```
object(MongoDB\Model\IndexInfo)#10 (4) {
["v"]=>
int(1)
["key"]=>
array(1) {
["_id"]=>
int(1)
}
["name"]=>
string(4) "_id_"
["ns"]=>
string(9) "demo.zips"
}
object(MongoDB\Model\IndexInfo)#13 (4) {
["v"]=>
int(1)
["key"]=>
array(1) {
["state"]=>
int(1)
}
["name"]=>
string(7) "state_1"
["ns"]=>
string(9) "demo.zips"
}
```
### Dropping Indexes
Indexes may be dropped via the [dropIndex()][dropindex] and
[dropIndexes()][dropindexes] methods. The following example drops a single index
by its name:
[dropindex]: ../classes/collection.md#dropindex
[dropindexes]: ../classes/collection.md#dropindexes
```
<?php
$collection = (new MongoDB\Client)->demo->zips;
$result = $collection->dropIndex('state_1');
var_dump($result);
```
The above example would output something similar to:
```
object(MongoDB\Model\BSONDocument)#11 (1) {
["storage":"ArrayObject":private]=>
array(2) {
["nIndexesWas"]=>
int(2)
["ok"]=>
float(1)
}
}
```
# Upgrade Guide
The MongoDB PHP Library and underlying [mongodb extension][ext-mongodb] have
notable API differences from the legacy [mongo extension][ext-mongo]. This page
will attempt to summarize those differences for the benefit of those upgrading
rom the legacy driver.
Additionally, a community-developed [mongo-php-adapter][adapter] library exists,
which implements the [mongo extension][ext-mongo] API using this library and the
new driver. While this adapter library is not officially supported by MongoDB,
it does bear mentioning.
[ext-mongo]: http://php.net/mongo
[ext-mongodb]: http://php.net/mongodb
[adapter]: https://github.com/alcaeus/mongo-php-adapter
## Collection API
This library's [MongoDB\Collection][collection] class implements MongoDB's
cross-driver [CRUD][crud-spec] and [Index Management][index-spec]
specifications. Although some method names have changed in accordance with the
new specifications, the new class provides the same functionality as the legacy
driver's [MongoCollection][mongocollection] class with some notable exceptions.
[collection]: classes/collection.md
[crud-spec]: https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst
[index-spec]: https://github.com/mongodb/specifications/blob/master/source/index-management.rst
[mongocollection]: http://php.net/mongocollection
### Old and New Methods
| [MongoCollection][mongocollection] | [MongoDB\Collection][collection] |
| --- | --- |
| [aggregate()](http://php.net/manual/en/mongocollection.aggregate.php) | [aggregate()](classes/collection.md#aggregate) |
| [aggregateCursor()](http://php.net/manual/en/mongocollection.aggregatecursor.php) | [aggregate()](classes/collection.md#aggregate) |
| [batchInsert()](http://php.net/manual/en/mongocollection.batchinsert.php) | [insertMany()](classes/collection.md#insertmany) |
| [count()](http://php.net/manual/en/mongocollection.count.php) | [count()](classes/collection.md#count) |
| [createDBRef()](http://php.net/manual/en/mongocollection.createdbref.php) | Not yet implemented ([PHPLIB-24][jira-dbref]) |
| [createIndex()](http://php.net/manual/en/mongocollection.createindex.php) | [createIndex()](classes/collection.md#createindex) |
| [deleteIndex()](http://php.net/manual/en/mongocollection.deleteindex.php) | [dropIndex()](classes/collection.md#dropindex) |
| [deleteIndexes()](http://php.net/manual/en/mongocollection.deleteindexes.php) | [dropIndexes()](classes/collection.md#dropindexes) |
| [drop()](http://php.net/manual/en/mongocollection.drop.php) | [drop()](classes/collection.md#drop) |
| [distinct()](http://php.net/manual/en/mongocollection.distinct.php) | [distinct()](classes/collection.md#distinct) |
| [ensureIndex()](http://php.net/manual/en/mongocollection.ensureindex.php) | [createIndex()](classes/collection.md#createindex) |
| [find()](http://php.net/manual/en/mongocollection.find.php) | [find()](classes/collection.md#find) |
| [findAndModify()](http://php.net/manual/en/mongocollection.findandmodify.php) | [findOneAndDelete()](classes/collection.md#findoneanddelete), [findOneAndReplace()](classes/collection.md#findoneandreplace), and [findOneAndUpdate()](classes/collection.md#findoneandupdate) |
| [findOne()](http://php.net/manual/en/mongocollection.findone.php) | [findOne()](classes/collection.md#findone) |
| [getDBRef()](http://php.net/manual/en/mongocollection.getdbref.php) | Not yet implemented ([PHPLIB-24][jira-dbref]) |
| [getIndexInfo()](http://php.net/manual/en/mongocollection.getindexinfo.php) | [listIndexes()](classes/collection.md#listindexes) |
| [getName()](http://php.net/manual/en/mongocollection.getname.php) | [getCollectionName()](classes/collection.md#getcollectionname) |
| [getReadPreference()](http://php.net/manual/en/mongocollection.getreadpreference.php) | Not implemented |
| [getSlaveOkay()](http://php.net/manual/en/mongocollection.getslaveokay.php) | Not implemented |
| [getWriteConcern()](http://php.net/manual/en/mongocollection.getwriteconcern.php) | Not implemented |
| [group()](http://php.net/manual/en/mongocollection.group.php) | Not yet implemented ([PHPLIB-177][jira-group]). Use [Database::command()](classes/database.md#command) for now. |
| [insert()](http://php.net/manual/en/mongocollection.insert.php) | [insertOne()](classes/collection.md#insertone) |
| [parallelCollectionScan()](http://php.net/manual/en/mongocollection.parallelcollectionscan.php) | Not implemented |
| [remove()](http://php.net/manual/en/mongocollection.remove.php) | [deleteMany()](classes/collection.md#deleteMany) and [deleteOne()](classes/collection.md#deleteone) |
| [save()](http://php.net/manual/en/mongocollection.save.php) | [insertOne()](classes/collection.md#insertone) or [replaceOne()](classes/collection.md#replaceone) with "upsert" option |
| [setReadPreference()](http://php.net/manual/en/mongocollection.setreadpreference.php) | Not implemented. Use [withOptions()](classes/collection.md#withoptions). |
| [setSlaveOkay()](http://php.net/manual/en/mongocollection.getslaveokay.php) | Not implemented |
| [setWriteConcern()](http://php.net/manual/en/mongocollection.setwriteconcern.php) | Not implemented. Use [withOptions()](classes/collection.md#withoptions). |
| [update()](http://php.net/manual/en/mongocollection.update.php) | [replaceOne()](classes/collection.md#replaceone), [updateMany()](classes/collection.md#updatemany), and [updateOne()](classes/collection.md#updateone) |
| [validate()](http://php.net/manual/en/mongocollection.validate.php) | Not implemented |
[jira-group]: https://jira.mongodb.org/browse/PHPLIB-177
[jira-dbref]: https://jira.mongodb.org/browse/PHPLIB-24
A guiding principle in designing the new APIs was that explicit method names
are preferable to overloaded terms found in the old API. For instance,
[MongoCollection::save()][save] and
[MongoCollection::findAndModify()][findandmodify] have very different modes of
operation, depending on their arguments. Methods were also split to distinguish
between [updating specific fields][update] and
[full-document replacement][replace].
[save]: http://php.net/manual/en/mongocollection.save.php
[findandmodify]: http://php.net/manual/en/mongocollection.findandmodify.php
[update]: https://docs.mongodb.org/manual/tutorial/modify-documents/#update-specific-fields-in-a-document
[replace]: https://docs.mongodb.org/manual/tutorial/modify-documents/#replace-the-document
### Group Command Helper
[MongoDB\Collection][collection] does not yet have a helper method for the
[group][group] command; however, that is planned in [PHPLIB-177][jira-group].
The following example demonstrates how to execute a group command using
[Database::command()](classes/database.md#command):
```php
<?php
$database = (new MongoDB\Client)->selectDatabase('db_name');
$cursor = $database->command([
'group' => [
'ns' => 'collection_name',
'key' => ['field_name' => 1],
'initial' => ['total' => 0],
'$reduce' => new MongoDB\BSON\Javascript('...'),
],
]);
$resultDocument = $cursor->toArray()[0];
```
[group]: https://docs.mongodb.org/manual/reference/command/group/
### MapReduce Command Helper
[MongoDB\Collection][collection] does not yet have a helper method for the
[mapReduce][mapReduce] command; however, that is planned in
[PHPLIB-53][jira-mapreduce]. The following example demonstrates how to execute a
mapReduce command using [Database::command()](classes/database.md#command):
```php
<?php
$database = (new MongoDB\Client)->selectDatabase('db_name');
$cursor = $database->command([
'mapReduce' => 'collection_name',
'map' => new MongoDB\BSON\Javascript('...'),
'reduce' => new MongoDB\BSON\Javascript('...'),
'out' => 'output_collection_name',
]);
$resultDocument = $cursor->toArray()[0];
```
[mapReduce]: https://docs.mongodb.org/manual/reference/command/mapReduce/
[jira-mapreduce]: https://jira.mongodb.org/browse/PHPLIB-53
### DBRef Helpers
[MongoDB\Collection][collection] does not yet have helper methods for working
with [DBRef][dbref] objects; however, that is planned in
[PHPLIB-24][jira-dbref].
[dbref]: https://docs.mongodb.org/manual/reference/database-references/#dbrefs
### MongoCollection::save() Removed
[MongoCollection::save()][save], which was syntactic sugar for an insert or
upsert operation, has been removed in favor of explicitly using
[insertOne()](classes/collection.md#insertone) or
[replaceOne()](classes/collection.md#replaceone) (with the "upsert" option).
![save() flowchart](img/save-flowchart.png)
While the [save()][save] method does have its uses for interactive environments,
such as the mongo shell, it was intentionally excluded from the
[CRUD][crud-spec] specification for language drivers. Generally, application
code should know if the document has an identifier and be able to explicitly
insert or replace the document and handle the returned InsertResult or
UpdateResult, respectively. This also helps avoid inadvertent and potentially
dangerous [full-document replacements][replace].
### MongoWriteBatch
The legacy driver's [MongoWriteBatch][batch] classes have been replaced with a
general-purpose [bulkWrite()](classes/collection.md#bulkwrite) method. Whereas
the legacy driver only allowed bulk operations of the same time, the new method
allows operations to be mixed (e.g. inserts, updates, and deletes).
[batch]: http://php.net/manual/en/class.mongowritebatch.php
......@@ -7,13 +7,21 @@ theme: readthedocs
pages:
- 'Home': 'index.md'
- 'Getting Started': 'getting-started.md'
- 'Example Data': 'example-data.md'
- 'Upgrade Guide': 'upgrade-guide.md'
- Tutorial:
- 'BSON Conversion': 'tutorial/bson.md'
- 'CRUD Operations': 'tutorial/crud.md'
- 'Database Commands': 'tutorial/commands.md'
- 'Indexes': 'tutorial/indexes.md'
- 'Example Data': 'tutorial/example-data.md'
- Classes:
- 'Client': 'classes/client.md'
- 'Database': 'classes/database.md'
- 'Collection': 'classes/collection.md'
markdown_extensions:
- def_list
- fenced_code
- smarty
- toc:
permalink: true
......@@ -76,7 +76,7 @@ class Client
/**
* Select a database.
*
* Note: collections whose names contain special characters (e.g. "-") may
* Note: databases whose names contain special characters (e.g. "-") may
* be selected with complex syntax (e.g. $client->{"that-database"}) or
* {@link selectDatabase()}.
*
......
......@@ -446,7 +446,7 @@ class Collection
* @see http://docs.mongodb.org/manual/core/read-operations-introduction/
* @param array|object $filter Query by which to filter documents
* @param array $options Additional options
* @return object|null
* @return array|object|null
*/
public function findOne($filter = [], array $options = [])
{
......@@ -471,7 +471,7 @@ class Collection
/**
* Finds a single document and deletes it, returning the original.
*
* The document to return may be null.
* The document to return may be null if no document matched the filter.
*
* Note: BSON deserialization of the returned document does not yet support
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
......@@ -499,9 +499,10 @@ class Collection
* Finds a single document and replaces it, returning either the original or
* the replaced document.
*
* The document to return may be null. By default, the original document is
* returned. Specify FindOneAndReplace::RETURN_DOCUMENT_AFTER for the
* "returnDocument" option to return the updated document.
* The document to return may be null if no document matched the filter. By
* default, the original document is returned. Specify
* FindOneAndReplace::RETURN_DOCUMENT_AFTER for the "returnDocument" option
* to return the updated document.
*
* Note: BSON deserialization of the returned document does not yet support
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
......@@ -530,9 +531,10 @@ class Collection
* Finds a single document and updates it, returning either the original or
* the updated document.
*
* The document to return may be null. By default, the original document is
* returned. Specify FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the
* "returnDocument" option to return the updated document.
* The document to return may be null if no document matched the filter. By
* default, the original document is returned. Specify
* FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the "returnDocument" option
* to return the updated document.
*
* Note: BSON deserialization of the returned document does not yet support
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
......@@ -580,7 +582,7 @@ class Collection
/**
* Return the collection namespace.
*
* @see http://docs.mongodb.org/manual/faq/developers/#faq-dev-namespace
* @see https://docs.mongodb.org/manual/reference/glossary/#term-namespace
* @return string
*/
public function getNamespace()
......@@ -691,7 +693,7 @@ class Collection
/**
* Updates at most one document matching the filter.
*
* @see ReplaceOne::__construct() for supported options
* @see UpdateOne::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/update/
* @param array|object $filter Query by which to filter documents
* @param array|object $update Update to apply to the matched document
......
......@@ -166,7 +166,7 @@ class Database
* @see CreateCollection::__construct() for supported options
* @param string $collectionName
* @param array $options
* @return object Command result document
* @return array|object Command result document
*/
public function createCollection($collectionName, array $options = [])
{
......
......@@ -36,8 +36,8 @@ class BulkWrite implements Executable
* Example array structure for all supported operation types:
*
* [
* [ 'deleteOne' => [ $filter ] ],
* [ 'deleteMany' => [ $filter ] ],
* [ 'deleteOne' => [ $filter ] ],
* [ 'insertOne' => [ $document ] ],
* [ 'replaceOne' => [ $filter, $replacement, $options ] ],
* [ 'updateMany' => [ $filter, $update, $options ] ],
......@@ -46,7 +46,7 @@ class BulkWrite implements Executable
*
* Arguments correspond to the respective Operation classes; however, the
* writeConcern option is specified for the top-level bulk write operation
* instead of each individual operations.
* instead of each individual operation.
*
* Supported options for replaceOne, updateMany, and updateOne operations:
*
......
......@@ -35,8 +35,9 @@ class CreateCollection implements Executable
* the size option must also be specified. The default is false.
*
* * flags (integer): Options for the MMAPv1 storage engine only. Must be a
* bitwise combination USE_POWER_OF_2_SIZES and NO_PADDING. The default
* is USE_POWER_OF_2_SIZES.
* bitwise combination CreateCollection::USE_POWER_OF_2_SIZES and
* CreateCollection::NO_PADDING. The default is
* CreateCollection::USE_POWER_OF_2_SIZES.
*
* * indexOptionDefaults (document): Default configuration for indexes when
* creating the collection.
......@@ -127,7 +128,7 @@ class CreateCollection implements Executable
*
* @see Executable::execute()
* @param Server $server
* @return object Command result document
* @return array|object Command result document
*/
public function execute(Server $server)
{
......
......@@ -22,6 +22,11 @@ class DropDatabase implements Executable
/**
* Constructs a dropDatabase command.
*
* Supported options:
*
* * typeMap (array): Type map for BSON deserialization. This will be used
* for the returned command result document.
*
* @param string $databaseName Database name
* @param array $options Command options
*/
......
......@@ -23,6 +23,11 @@ class DropIndexes implements Executable
/**
* Constructs a dropIndexes command.
*
* Supported options:
*
* * typeMap (array): Type map for BSON deserialization. This will be used
* for the returned command result document.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param string $indexName Index name (use "*" to drop all indexes)
......
......@@ -2,6 +2,7 @@
namespace MongoDB\Operation;
use MongoDB\Driver\Cursor;
use MongoDB\Driver\Query;
use MongoDB\Driver\ReadConcern;
use MongoDB\Driver\ReadPreference;
......
......@@ -74,7 +74,7 @@ class FindOne implements Executable
*
* @see Executable::execute()
* @param Server $server
* @return object|null
* @return array|object|null
*/
public function execute(Server $server)
{
......
......@@ -35,8 +35,10 @@ class FindOneAndReplace implements Executable
* document.
*
* * returnDocument (enum): Whether to return the document before or after
* the update is applied. Must be either RETURN_DOCUMENT_BEFORE or
* RETURN_DOCUMENT_AFTER. The default is RETURN_DOCUMENT_BEFORE.
* the update is applied. Must be either
* FindOneAndReplace::RETURN_DOCUMENT_BEFORE or
* FindOneAndReplace::RETURN_DOCUMENT_AFTER. The default is
* FindOneAndReplace::RETURN_DOCUMENT_BEFORE.
*
* * sort (document): Determines which document the operation modifies if
* the query selects multiple documents.
......
......@@ -35,8 +35,10 @@ class FindOneAndUpdate implements Executable
* document.
*
* * returnDocument (enum): Whether to return the document before or after
* the update is applied. Must be either RETURN_DOCUMENT_BEFORE or
* RETURN_DOCUMENT_AFTER. The default is RETURN_DOCUMENT_BEFORE.
* the update is applied. Must be either
* FindOneAndUpdate::RETURN_DOCUMENT_BEFORE or
* FindOneAndUpdate::RETURN_DOCUMENT_AFTER. The default is
* FindOneAndUpdate::RETURN_DOCUMENT_BEFORE.
*
* * sort (document): Determines which document the operation modifies if
* the query selects multiple documents.
......
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