Commit d9aee1d9 authored by Jeremy Mikola's avatar Jeremy Mikola

Merge pull request #185

parents faf8a1d8 b4eed02b
......@@ -11,6 +11,38 @@ the [MongoDB Manual][crud].
[crud-spec]: https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst
[crud]: https://docs.mongodb.org/manual/crud/
This page covers the following common use cases:
* Querying for [one](#finding-one-document) or [many](#finding-many-documents)
documents at a time
* [Projecting](#query-projection) fields in a query
* Applying [limit, sort, and skip options](#limit-sort-and-skip-options) to a
query
* Inserting [one](#inserting-one-document) or [many](#inserting-many-documents)
documents at a time
* Updating [one](#updating-one-document) or [many](#updating-many-documents)
documents at a time
* [Replacing](#replacing-a-document) a document
* [Upserting](#upserting-a-document) a document
* Deleting [one](#deleting-one-document) or [many](#deleting-many-documents)
documents at a time
* [Aggregating](#aggregating-documents) documents
Note that the use of arrays to express documents in the following examples was
done for simplicity. The driver will also accept instances of stdClass or
[MongoDB\BSON\Serializable][serializable]) for these arguments (e.g. query
filters, inserted documents, update documents).
[serializable]: http://php.net/mongodb-bson-serializable
Documents destined for database storage (e.g. insert documents, replacement
documents, embedded documents included in an update operation) may also be
instances of [MongoDB\BSON\Persistable][persistable]. See
[Persistable Classes][persistable-classes] for more information.
[persistable]: http://php.net/mongodb-bson-persistable
[persistable-classes]: bson.md#persistable-classes
## Finding One Document
The [findOne()][findone] method returns the first matched document, or null if
......@@ -160,7 +192,398 @@ The above example would output something similar to:
90201: BELL GARDENS, CA
```
## Aggregation
## Inserting One Document
The [insertOne()][insertone] method may be used to insert a single document.
This method returns an instance of `MongoDB\InsertOneResult`, which may be used
to access the ID of the inserted document. Note that if a document does not
contain an `_id` field at the time of insertion, the driver will generate a
`MongoDB\BSON\ObjectID` to use as its ID.
[insertone]: ../classes/collection.md#insertone
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$insertOneResult = $collection->insertOne(['name' => 'Bob']);
printf("Inserted %d document(s)\n", $insertOneResult->getInsertedCount());
var_dump($insertOneResult->getInsertedId());
```
The above example would output something similar to:
```
Inserted 1 document(s)
object(MongoDB\BSON\ObjectID)#10 (1) {
["oid"]=>
string(24) "5750905b6118fd170565aa81"
}
```
The following example inserts a document with an ID. Note that if an ID is not
unique for the collection, the insert will fail due to a duplicate key error.
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$insertOneResult = $collection->insertOne(['_id' => 1, 'name' => 'Alice']);
printf("Inserted %d document(s)\n", $insertOneResult->getInsertedCount());
var_dump($insertOneResult->getInsertedId());
```
The above example would output:
```
Inserted 1 document(s)
int(1)
```
## Inserting Many Documents
The [insertMany()][insertmany] method may be used to insert multiple documents
at a time. This method returns an instance of `MongoDB\InsertManyResult`, which
may be used to access the IDs of the inserted documents.
[insertmany]: ../classes/collection.md#insertmany
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$insertManyResult = $collection->insertMany([
['name' => 'Bob'],
['_id' => 1, 'name' => 'Alice'],
]);
printf("Inserted %d document(s)\n", $insertManyResult->getInsertedCount());
var_dump($insertManyResult->getInsertedIds());
```
The above example would output something similar to:
```
Inserted 2 document(s)
array(2) {
[0]=>
object(MongoDB\BSON\ObjectID)#10 (1) {
["oid"]=>
string(24) "5750927b6118fd1ed64eb141"
}
[1]=>
int(1)
}
```
## Updating One Document
The [updateOne()][updateone] method may be used to update a single document
matching a filter. This method returns an instance of `MongoDB\UpdateResult`,
which may be used to access statistics about the update operation.
[updateone]: ../classes/collection.md#updateone
This method has two required parameters: a query filter and an update document.
The query filter is similar to what might be provided to [find()][find]. The
update document consists of one or more [update operators][updateops].
[updateops]: https://docs.mongodb.com/manual/reference/operator/update/
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
$collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
$updateResult = $collection->updateOne(
['state' => 'ny'],
['$set' => ['country' => 'us']]
);
printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
```
The above example would output something similar to:
```
Matched 1 document(s)
Modified 1 document(s)
```
Note that it is possible for a document to match the filter but not be modified
by an update:
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
$updateResult = $collection->updateOne(
['name' => 'Bob'],
['$set' => ['state' => 'ny']]
);
printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
```
The above example would output something similar to:
```
Matched 1 document(s)
Modified 0 document(s)
```
## Updating Many Documents
The [updateMany()][updatemany] method may be used to update multiple documents
at a time. This method returns an instance of `MongoDB\UpdateResult`, which may
be used to access statistics about the update operation.
[updatemany]: ../classes/collection.md#updatemany
This method has two required parameters: a query filter and an update document.
The query filter is similar to what might be provided to [find()][find]. The
update document consists of one or more [update operators][updateops].
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$collection->insertOne(['name' => 'Bob', 'state' => 'ny', 'country' => 'us']);
$collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
$collection->insertOne(['name' => 'Sam', 'state' => 'ny']);
$updateResult = $collection->updateMany(
['state' => 'ny'],
['$set' => ['country' => 'us']]
);
printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
```
The above example would output something similar to:
```
Matched 3 document(s)
Modified 2 document(s)
```
## Replacing a Document
The [replaceOne()][replaceone] method may be used to replace a single document
matching a filter. This method returns an instance of `MongoDB\UpdateResult`,
which may be used to access statistics about the replacement operation.
[replaceone]: ../classes/collection.md#replaceone
This method has two required parameters: a query filter and a replacement
document. The query filter is similar to what might be provided to
[find()][find]. The replacement document will be used to overwrite the matched
document (excluding its ID, which is immutable) and must not contain
[update operators][updateops].
Note that the very nature of a replacement operation makes it easy to
inadvertently overwrite or delete fields in a document. When possible, users
should consider updating individual fields with [updateOne()][updateone] or
[updateMany()][updatemany].
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
$updateResult = $collection->replaceOne(
['name' => 'Bob'],
['name' => 'Robert', 'state' => 'ca']
);
printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
```
The above example would output something similar to:
```
Matched 1 document(s)
Modified 1 document(s)
```
Note that it is possible for a document to match the filter but not be modified
by a replacement (i.e. the matched document and replacement may be the same).
## Upserting a Document
An upsert is a variation of an update or replace operation, whereby a new
document is inserted if the query filter does not match an existing document.
An upsert may be specified via the `upsert` option for [updateOne()][updateone],
[updateMany()][updatemany], or [replaceOne()][replaceone]. The logic by which
the inserted document is created is discussed in the [MongoDB manual][upsert].
[upsert]: https://docs.mongodb.com/manual/reference/method/db.collection.update/#upsert-parameter
If a document has been upserted, its ID will be accessible via
`MongoDB\UpdateResult::getUpsertedId()`.
The following example demonstrates an upsert via [updateOne()][updateone]:
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$updateResult = $collection->updateOne(
['name' => 'Bob'],
['$set' => ['state' => 'ny']],
['upsert' => true]
);
printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
var_dump($collection->findOne(['_id' => $updateResult->getUpsertedId()]));
```
The above example would output something similar to:
```
Matched 0 document(s)
Modified 0 document(s)
object(MongoDB\Model\BSONDocument)#16 (1) {
["storage":"ArrayObject":private]=>
array(3) {
["_id"]=>
object(MongoDB\BSON\ObjectID)#15 (1) {
["oid"]=>
string(24) "57509c4406d7241dad86e7c3"
}
["name"]=>
string(3) "Bob"
["state"]=>
string(2) "ny"
}
}
```
The following example demonstrates an upsert via [replaceOne()][replaceone]:
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$updateResult = $collection->replaceOne(
['name' => 'Bob'],
['name' => 'Alice', 'state' => 'ny'],
['upsert' => true]
);
printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
var_dump($collection->findOne(['_id' => $updateResult->getUpsertedId()]));
```
The above example would output something similar to:
```
Matched 0 document(s)
Modified 0 document(s)
object(MongoDB\Model\BSONDocument)#16 (1) {
["storage":"ArrayObject":private]=>
array(3) {
["_id"]=>
object(MongoDB\BSON\ObjectID)#15 (1) {
["oid"]=>
string(24) "57509c6606d7241dad86e7c4"
}
["name"]=>
string(5) "Alice"
["state"]=>
string(2) "ny"
}
}
```
## Deleting One Document
The [deleteOne()][deleteone] method may be used to delete a single document
matching a filter. This method returns an instance of `MongoDB\DeleteResult`,
which may be used to access statistics about the delete operation.
[deleteone]: ../classes/collection.md#deleteone
This method has two required parameters: a query filter. The query filter is
similar to what might be provided to [find()][find].
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
$collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
$deleteResult = $collection->deleteOne(['state' => 'ny']);
printf("Deleted %d document(s)\n", $deleteResult->getDeletedCount());
```
The above example would output something similar to:
```
Deleted 1 document(s)
```
## Deleting Many Documents
The [deleteMany()][deletemany] method may be used to delete multiple documents
at a time. This method returns an instance of `MongoDB\DeleteResult`, which may
be used to access statistics about the delete operation.
[deletemany]: ../classes/collection.md#deletemany
This method has two required parameters: a query filter. The query filter is
similar to what might be provided to [find()][find].
```
<?php
$collection = (new MongoDB\Client)->demo->users;
$collection->drop();
$collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
$collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
$deleteResult = $collection->deleteMany(['state' => 'ny']);
printf("Deleted %d document(s)\n", $deleteResult->getDeletedCount());
```
The above example would output something similar to:
```
Deleted 2 document(s)
```
## Aggregating Documents
The [Aggregation Framework][aggregation] may be used to issue complex queries
that filter, transform, and group collection data. The [aggregate()][aggregate]
......
<?php
if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
// Dependencies were installed with Composer and this is the main project
$loader = require_once __DIR__ . '/../vendor/autoload.php';
} elseif (file_exists(__DIR__ . '/../../../../autoload.php')) {
// We're installed as a dependency in another project's `vendor` directory
$loader = require_once __DIR__ . '/../../../../autoload.php';
} else {
throw new Exception('Can\'t find autoload.php. Did you install dependencies with Composer?');
}
<?php
require_once __DIR__ . "/bootstrap.php";
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$collection = new MongoDB\Collection($manager, "phplib_demo.bulkwrite");
function dumpWriteResults(MongoDB\BulkWriteResult $result)
{
printf("Inserted %d documents, upserted %d, updated %d, and deleted %d\n",
$result->getInsertedCount(),
$result->getUpsertedCount(),
$result->getModifiedCount(),
$result->getDeletedCount()
);
if ($result->getUpsertedCount()) {
foreach ($result->getUpsertedIds() as $index => $id) {
printf("upsertedId[%d]: %s\n", $index, $id);
}
}
}
function dumpCollection($collection)
{
printf("Dumping all documents in: %s.%s\n",
$collection->getDatabaseName(),
$collection->getCollectionName()
);
$n = 0;
foreach($collection->find() as $document) {
var_dump($document);
$n++;
}
printf("Found %d documents\n", $n);
}
$result = $collection->bulkWrite([
[
"insertOne" => [
[
"name" => "Hannes Magnusson",
"company" => "10gen",
]
],
],
[
"insertOne" => [
[
"name" => "Jeremy Mikola",
"company" => "10gen",
]
],
],
[
"updateMany" => [
["company" => "10gen"],
['$set' => ["company" => "MongoDB"]],
],
],
[
"updateOne" => [
["name" => "Hannes Magnusson"],
['$set' => ["viking" => true]],
],
],
]);
dumpWriteResults($result);
echo "\n";
dumpCollection($collection);
echo "\n";
$result = $collection->bulkWrite([
[
"deleteOne" => [
["company" => "MongoDB"],
],
],
[
"updateOne" => [
["name" => "Hannes Magnusson"],
['$set' => ["nationality" => "Icelandic"]],
["upsert" => true],
],
],
[
"deleteMany" => [
["nationality" => [ '$ne' => "Icelandic"]],
],
],
]);
dumpWriteResults($result);
echo "\n";
dumpCollection($collection);
echo "\n";
$result = $collection->bulkWrite([
[
"deleteMany" => [
[],
],
],
]);
dumpWriteResults($result);
echo "\n";
dumpCollection($collection);
<?php
require_once __DIR__ . "/bootstrap.php";
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$collection = new MongoDB\Collection($manager, "phplib_demo.write");
$hannes = [
"name" => "Hannes",
"nick" => "bjori",
"citizen" => "Iceland",
];
$hayley = [
"name" => "Bayley",
"nick" => "Ninja",
"citizen" => "USA",
];
$bobby = [
"name" => "Robert Fischer",
"nick" => "Bobby Fischer",
"citizen" => "USA",
];
$kasparov = [
"name" => "Garry Kimovich Kasparov",
"nick" => "Kasparov",
"citizen" => "Russia",
];
$spassky = [
"name" => "Boris Vasilievich Spassky",
"nick" => "Spassky",
"citizen" => "France",
];
try {
$result = $collection->insertOne($hannes);
printf("Inserted _id: %s\n\n", $result->getInsertedId());
$result = $collection->insertOne($hayley);
printf("Inserted _id: %s\n\n", $result->getInsertedId());
$result = $collection->insertOne($bobby);
printf("Inserted _id: %s\n\n", $result->getInsertedId());
$count = $collection->count(["nick" => "bjori"]);
printf("Searching for nick => bjori, should have only one result: %d\n\n", $count);
$result = $collection->updateOne(
["citizen" => "USA"],
['$set' => ["citizen" => "Iceland"]]
);
printf("Updated: %s (out of expected 1)\n\n", $result->getModifiedCount());
$cursor = $collection->find(
["citizen" => "Iceland"],
["comment" => "Excellent query"]
);
echo "Searching for citizen => Iceland, verify Bayley is now Icelandic\n";
foreach($cursor as $document) {
var_dump($document);
}
echo "\n";
} catch(Exception $e) {
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
exit;
}
try {
$cursor = $collection->find();
echo "Find all docs, should be 3, verify 1x USA citizen, 2x Icelandic\n";
foreach($cursor as $document) {
var_dump($document);
}
echo "\n";
$result = $collection->distinct("citizen");
echo "Distinct countries:\n";
var_dump($result);
echo "\n";
echo "aggregate\n";
$result = $collection->aggregate(
[
['$project' => ["name" => 1, "_id" => 0]],
],
[ "useCursor" => true, "batchSize" => 2 ]
);
printf("Should be 3 different people\n");
foreach($result as $person) {
var_dump($person);
}
echo "\n";
} catch(Exception $e) {
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
exit;
}
try {
$result = $collection->updateMany(
["citizen" => "Iceland"],
['$set' => ["viking" => true]]
);
printf("Updated: %d (out of expected 2), verify Icelandic people are vikings\n", $result->getModifiedCount());
$result = $collection->find();
foreach($result as $document) {
var_dump($document);
}
echo "\n";
} catch(Exception $e) {
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
exit;
}
try {
$result = $collection->replaceOne(
["nick" => "Bobby Fischer"],
["name" => "Magnus Carlsen", "nick" => "unknown", "citizen" => "Norway"]
);
printf("Replaced: %d (out of expected 1), verify Bobby has been replaced with Magnus\n", $result->getModifiedCount());
$result = $collection->find();
foreach($result as $document) {
var_dump($document);
}
echo "\n";
} catch(Exception $e) {
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
exit;
}
try {
$result = $collection->deleteOne($document);
printf("Deleted: %d (out of expected 1)\n\n", $result->getDeletedCount());
$result = $collection->deleteMany(["citizen" => "Iceland"]);
printf("Deleted: %d (out of expected 2)\n\n", $result->getDeletedCount());
} catch(Exception $e) {
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
exit;
}
try {
echo "FindOneAndReplace\n";
$result = $collection->findOneAndReplace(
$spassky,
$kasparov,
["upsert" => true]
);
echo "Kasparov\n";
var_dump($result);
echo "\n";
echo "Returning the old document where he was Russian\n";
$result = $collection->findOneAndUpdate(
$kasparov,
['$set' => ["citizen" => "Croatia"]]
);
var_dump($result);
echo "\n";
echo "Deleting him, he isn't Croatian just yet\n";
$result = $collection->findOneAndDelete(["citizen" => "Croatia"]);
var_dump($result);
echo "\n";
echo "This should be empty\n";
$result = $collection->find();
foreach($result as $document) {
var_dump($document);
}
echo "\n";
} catch(Exception $e) {
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
exit;
}
try {
$result = $collection->bulkWrite(
// Required writes param (an array of operations)
[
// Operations identified by single key
[
'insertOne' => [
['x' => 1]
],
],
[
'updateMany' => [
['x' => 1],
['$set' => ['x' => 2]],
],
],
[
'updateOne' => [
['x' => 3],
['$set' => ['x' => 4]],
// Optional params are still permitted
['upsert' => true],
],
],
[
'deleteOne' => [
['x' => 1],
],
],
[
'deleteMany' => [
// Required arguments must still be specified
[],
],
],
],
// Optional named params in an associative array
['ordered' => false]
);
printf("insertedCount: %d\n", $result->getInsertedCount());
printf("matchedCount: %d\n", $result->getMatchedCount());
printf("modifiedCount: %d\n", $result->getModifiedCount());
printf("upsertedCount: %d\n", $result->getUpsertedCount());
printf("deletedCount: %d\n", $result->getDeletedCount());
foreach ($result->getUpsertedIds() as $index => $id) {
printf("upsertedId[%d]: %s\n", $index, $id);
}
} catch(Exception $e) {
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
exit;
}
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