Tutorial
This is the 10gen-supported PHP driver for MongoDB.
Here's a quick code sample that connects, inserts documents, queries for
documents, iterates through query results, and disconnects from MongoDB.
There are more details on each step in the tutorial below.
comedy;
// select a collection (analogous to a relational database's table)
$collection = $db->cartoons;
// add a record
$document = array( "title" => "Calvin and Hobbes", "author" => "Bill Watterson" );
$collection->insert($document);
// add another record, with a different "shape"
$document = array( "title" => "XKCD", "online" => true );
$collection->insert($document);
// find everything in the collection
$cursor = $collection->find();
// iterate through the results
foreach ($cursor as $document) {
echo $document["title"] . "\n";
}
?>
]]>
&example.outputs;
Making a Connection
To connect to the database server, use one of the following:
]]>
You do not have to explicitly disconnect from the database. The driver uses
persistent connections and will re-use already established connections.
See Also
The chapter on connecting
covers different types of connections.
The API documentation on the MongoClient class and
MongoClient::__construct give a comprehensive look at
all possible options with a number of examples.
Getting a Database
To select a database, use:
dbname;
?>
]]>
The database does not need to be created in advance, you can create new
databases by selecting them.
Be careful of typos! You can inadvertently create a new database, which can
cause confusing errors (here name is misspelled as
anme in the second selection:
mybiglongdbname;
// do some stuff
$db = $connection->mybiglongdbanme;
// now connected to a different database!
?>
]]>
See Also
The API documentation on the MongoDB class contains
more information about database objects.
Getting A Collection
Getting a collection has the same syntax as getting a database:
baz;
// select a collection:
$collection = $db->foobar;
// or, directly selecting a database and collection:
$collection = $connection->baz->foobar;
?>
]]>
A collection is analogous to a table (if you are familiar with relational
databases).
See Also
The API documentation on the MongoCollection class
contains more information about collection objects.
Inserting a Document
Associative arrays are the basic object that can be saved to a collection in
the database. A somewhat random "document" might be:
"MongoDB",
"type" => "database",
"count" => 1,
"info" => (object)array( "x" => 203, "y" => 102),
"versions" => array("0.9.7", "0.9.8", "0.9.9")
);
?>
]]>
Note that you can have nested arrays and objects. The driver will always
store an associative array as an object in the database. A
numerically indexed array is stored as an array in case the keys start at
0 and are not interrupted, and as an object if the array keys don't start
at 0 or have gaps (ie: 0, 1, 4, 5).
To insert this document, use MongoCollection::insert:
database->collectionName;
$collection->insert( $doc );
?>
]]>
See Also
The API documentation on MongoCollection::insert
contains more information about inserting data.
Finding Documents using MongoCollection::findOne
To show that the document we inserted in the previous step is stored in
the database, we can do a simple
MongoCollection::findOne operation to get a single
document from the collection. This method is useful when there is only one
document matching the query or you are only interested in one result.
database->collectionName;
$document = $collection->findOne();
var_dump( $document );
?>
]]>
&example.outputs;
object(MongoId)#8 (1) {
["$id"]=>
string(24) "4e2995576803fab768000000"
}
["name"]=>
string(7) "MongoDB"
["type"]=>
string(8) "database"
["count"]=>
int(1)
["info"]=>
array(2) {
["x"]=>
int(203)
["y"]=>
int(102)
}
["versions"]=>
array(3) {
[0]=>
string(5) "0.9.7"
[1]=>
string(5) "0.9.8"
[2]=>
string(5) "0.9.9"
}
}
]]>
Note that there is an _id field that has been added
automatically to your document. _id is the "primary key"
field. If your document does not specify one, the driver will add one
automatically.
If you specify your own _id field, it must be unique to
the collection. See the example here:
database;
$db->foo->insert(array("_id" => 1));
// this will throw an exception
$db->foo->insert(array("_id" => 1));
// this is fine, as it is a different collection
$db->bar->insert(array("_id" => 1));
?>
]]>
By default the driver will ensure the server has acknowledged the write
before returning. You can optionally turn this behaviour off by passing
array("w" => 0) as the second argument. This means that
the driver should not wait for the database to acknowledge the write and
would not throw the duplicate _id exception.
See AlsoMongoCollection::findOne for more information about
finding data.
MongoId goes into more detail on unique ids.
The writes section covers
writes in more depth, and the
chapter goes into details of the various Write Concern options.
Adding Multiple Documents
In order to do more interesting things with queries, let's add multiple
simple documents to the collection. These documents will just be of the form
array( "i" => value ); and we
can do this fairly efficiently in a loop:
database->collectionName;
for ( $i = 0; $i < 100; $i++ )
{
$collection->insert( array( 'i' => $i, "field{$i}" => $i * 2 ) );
}
?>
]]>
Notice that we can insert arrays with different keys into the same
collection. This aspect is what we mean when we say that MongoDB is
"schema-free". In the example above each document has an
i field, but also a field name in the form of
field + $i.
Counting Documents in A Collection
Now that we've inserted 101 documents (the 100 we did in the loop, plus the
first one), we can check to see if we have them all using the
MongoCollection::count method.
database->collectionName;
echo $collection->count();
?>
]]>
and it should print 101.
Using a Cursor to Get All of the Documents
In order to get all the documents in the collection, we will use
MongoCollection::find. The find() method returns a
MongoCursor object which allows us to iterate over the
set of documents that matched our query. So to query all of the documents and
print them out:
database->collectionName;
$cursor = $collection->find();
foreach ( $cursor as $id => $value )
{
echo "$id: ";
var_dump( $value );
}
?>
]]>
and that should print all 101 documents in the collection.
$id is the _id field of a document
(cast to a string) and $value is the document itself.
See Also
The API documentation on MongoCollection::find
contains more information about finding data.
Setting Criteria for a Query
We can create a query to pass to the
MongoCollection::find method to get a subset of the
documents in our collection. For example, if we wanted to find the document
for which the value of the "i" field is
71, we would do the following:
database->collectionName;
$query = array( 'i' => 71 );
$cursor = $collection->find( $query );
while ( $cursor->hasNext() )
{
var_dump( $cursor->getNext() );
}
?>
]]>
&example.outputs;
object(MongoId)#6 (0) {
}
["i"]=>
int(71)
["_ns"]=>
"testCollection"
}
]]>
Getting A Set of Documents With a Query
We can use the query to get a set of documents from our collection. For
example, if we wanted to get all documents where "i"
> 50, we could write:
database->collectionName;
$query = array( "i" => array( '$gt' => 50 ) ); //note the single quotes around '$gt'
$cursor = $coll->find( $query );
while ( $cursor->hasNext() )
{
var_dump( $cursor->getNext() );
}
?>
]]>
which should print the documents where "i" >
50. We could also get a range, say
20 < i <= 30:
database->collectionName;
$query = array( 'i' => array( '$gt' => 20, "\$lte" => 30 ) );
$cursor = $coll->find( $query );
while ( $cursor->hasNext() )
{
var_dump( $cursor->getNext() );
}
?>
]]>
Remember to always escape the $-symbol or use single quotes. Otherwise PHP
will interpret it to be the variable $gt.
Creating An Index
MongoDB supports indexes, and they are very easy to add on a collection. To
create an index, you specify the field name and direction: ascending (1) or
descending (-1). The following creates an ascending index on the "i" field:
database->collectionName;
$coll->ensureIndex( array( "i" => 1 ) ); // create index on "i"
$coll->ensureIndex( array( "i" => -1, "j" => 1 ) ); // index on "i" descending, "j" ascending
?>
]]>
Indexing is critical for good read performance as your data grows. If you
are not familiar with indexing, check out the
MongoCollection::ensureIndex documentation and the core
MongoDB indexing documentation.