Commit 0a3b8270 authored by Jeremy Mikola's avatar Jeremy Mikola

Add query examples and create BSON tutorial page

parent 48e60f4b
# 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"
}
```
...@@ -11,21 +11,12 @@ the [MongoDB Manual][crud]. ...@@ -11,21 +11,12 @@ the [MongoDB Manual][crud].
[crud-spec]: https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst [crud-spec]: https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst
[crud]: https://docs.mongodb.org/manual/crud/ [crud]: https://docs.mongodb.org/manual/crud/
## Querying ## Finding One Document
### Finding One Document
The [findOne()][findone] method returns the first matched document, or null if The [findOne()][findone] method returns the first matched document, or null if
no document was matched. By default, the library returns BSON documents and no document was matched.
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.
[findone]: ../classes/collection.md#findone [findone]: ../classes/collection.md#findone
[arrayobject]: http://php.net/arrayobject
[serializable]: http://php.net/mongodb-bson-serializable
[unserializable]: http://php.net/mongodb-bson-unserializable
``` ```
<?php <?php
...@@ -65,12 +56,46 @@ object(MongoDB\Model\BSONDocument)#13 (1) { ...@@ -65,12 +56,46 @@ object(MongoDB\Model\BSONDocument)#13 (1) {
} }
``` ```
Most methods that read data from MongoDB support a "typeMap" option, which ## Finding Many Documents
allows control over how BSON is converted to PHP. If desired, this option can be
used to return everything as a PHP array, as was done in the legacy The [find()][find] method returns a [MongoDB\Driver\Cursor][cursor] object,
[mongo extension][ext-mongo]: 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/
[ext-mongo]: http://php.net/mongo
``` ```
<?php <?php
...@@ -78,8 +103,8 @@ used to return everything as a PHP array, as was done in the legacy ...@@ -78,8 +103,8 @@ used to return everything as a PHP array, as was done in the legacy
$collection = (new MongoDB\Client)->demo->zips; $collection = (new MongoDB\Client)->demo->zips;
$document = $collection->findOne( $document = $collection->findOne(
['_id' => '94301'], ['_id' => '10011'],
['typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']] ['projection' => ['pop => 1']]
); );
var_dump($document); var_dump($document);
...@@ -88,39 +113,37 @@ var_dump($document); ...@@ -88,39 +113,37 @@ var_dump($document);
The above example would output something similar to: The above example would output something similar to:
``` ```
array(5) { object(MongoDB\Model\BSONDocument)#12 (1) {
["_id"]=> ["storage":"ArrayObject":private]=>
string(5) "94301"
["city"]=>
string(9) "PALO ALTO"
["loc"]=>
array(2) { array(2) {
[0]=> ["_id"]=>
float(-122.149685) string(5) "10011"
[1]=> ["pop"]=>
float(37.444324) int(46560)
} }
["pop"]=>
int(15965)
["state"]=>
string(2) "CA"
} }
``` ```
### Finding Many Documents **Note:** the "_id" field is included by default unless explicitly excluded.
The [find()][find] method returns a [MongoDB\Driver\Cursor][cursor] object, ## Limit, Sort, and Skip Options
which may be iterated upon to access all matched documents.
[find]: ../classes/collection.md#find In addition to criteria, queries may take options to limit, sort, and skip
[cursor]: http://php.net/mongodb-driver-cursor returned documents. The following example queries for the five most populous
zip codes in the United States:
``` ```
<?php <?php
$collection = (new MongoDB\Client)->demo->zips; $collection = (new MongoDB\Client)->demo->zips;
$cursor = $collection->find(['city' => 'JERSEY CITY', 'state' => 'NJ']); $cursor = $collection->find(
[],
[
'limit' => 5,
'sort' => ['pop' => -1],
]
);
foreach ($cursor as $document) { foreach ($cursor as $document) {
echo $document['_id'], "\n"; echo $document['_id'], "\n";
...@@ -130,10 +153,9 @@ foreach ($cursor as $document) { ...@@ -130,10 +153,9 @@ foreach ($cursor as $document) {
The above example would output something similar to: The above example would output something similar to:
``` ```
07302 60623: CHICAGO, IL
07304 11226: BROOKLYN, NY
07305 10021: NEW YORK, NY
07306 10025: NEW YORK, NY
07307 90201: BELL GARDENS, CA
07310
``` ```
...@@ -9,6 +9,7 @@ pages: ...@@ -9,6 +9,7 @@ pages:
- 'Getting Started': 'getting-started.md' - 'Getting Started': 'getting-started.md'
- 'Upgrade Guide': 'upgrade-guide.md' - 'Upgrade Guide': 'upgrade-guide.md'
- Tutorial: - Tutorial:
- 'BSON Conversion': 'tutorial/bson.md'
- 'CRUD Operations': 'tutorial/crud.md' - 'CRUD Operations': 'tutorial/crud.md'
- 'Database Commands': 'tutorial/commands.md' - 'Database Commands': 'tutorial/commands.md'
- 'Indexes': 'tutorial/indexes.md' - 'Indexes': 'tutorial/indexes.md'
......
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