php-doc-en/reference/mongo/tutorial.xml
2015-11-19 13:46:44 +00:00

576 lines
16 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<chapter xml:id="mongo.tutorial" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Tutorial</title>
<warning>
&mongo.deprecated.note;
</warning>
<para>
This is the official MongoDB driver for PHP.
</para>
<para>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.
</para>
<example xml:id="mongo.tutorial.basics">
<programlisting role="php">
<![CDATA[
<?php
// connect
$m = new MongoClient();
// select a database
$db = $m->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";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Calvin and Hobbes
XKCD
]]>
</screen>
</example>
<section xml:id="mongo.tutorial.connecting">
<title>Making a Connection</title>
<para>
To connect to the database server, use one of the following:
</para>
<example xml:id="mongo.tutorial.connecting-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient(); // connects to localhost:27017
$connection = new MongoClient( "mongodb://example.com" ); // connect to a remote host (default port: 27017)
$connection = new MongoClient( "mongodb://example.com:65432" ); // connect to a remote host at a given port
?>
]]>
</programlisting>
</example>
<para>
You do not have to explicitly disconnect from the database. The driver uses
persistent connections and will re-use already established connections.
</para>
<section xml:id="mongo.tutorial.connecting.seealso">
<title>See Also</title>
<para>
The chapter on <link linkend="mongo.connecting">connecting</link>
covers different types of connections.
</para>
<para>
The API documentation on the <classname>MongoClient</classname> class and
<function>MongoClient::__construct</function> give a comprehensive look at
all possible options with a number of examples.
</para>
</section>
</section>
<section xml:id="mongo.tutorial.selectdb">
<title>Getting a Database</title>
<para>
To select a database, use:
</para>
<example xml:id="mongo.tutorial.selectdb-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$db = $connection->dbname;
?>
]]>
</programlisting>
</example>
<para>
The database does not need to be created in advance, you can create new
databases by selecting them.
</para>
<para>
Be careful of typos! You can inadvertently create a new database, which can
cause confusing errors (here <literal>name</literal> is misspelled as
<literal>anme</literal> in the second selection:
<example xml:id="mongo.tutorial.selectdb.typo">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$db = $connection->mybiglongdbname;
// do some stuff
$db = $connection->mybiglongdbanme;
// now connected to a different database!
?>
]]>
</programlisting>
</example>
</para>
<section xml:id="mongo.tutorial.selectdb.seealso">
<title>See Also</title>
<para>
The API documentation on the <classname>MongoDB</classname> class contains
more information about database objects.
</para>
</section>
</section>
<section xml:id="mongo.tutorial.collection">
<title>Getting A Collection</title>
<para>
Getting a collection has the same syntax as getting a database:
</para>
<example xml:id="mongo.tutorial.collection-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$db = $connection->baz;
// select a collection:
$collection = $db->foobar;
// or, directly selecting a database and collection:
$collection = $connection->baz->foobar;
?>
]]>
</programlisting>
</example>
<para>
A collection is analogous to a table (if you are familiar with relational
databases).
</para>
<section xml:id="mongo.tutorial.collection.seealso">
<title>See Also</title>
<para>
The API documentation on the <classname>MongoCollection</classname> class
contains more information about collection objects.
</para>
</section>
</section>
<section xml:id="mongo.tutorial.insert">
<title>Inserting a Document</title>
<para>
Associative arrays are the basic object that can be saved to a collection in
the database. A somewhat random "document" might be:
</para>
<example xml:id="mongo.tutorial.insert-data-example">
<programlisting role="php">
<![CDATA[
<?php
$doc = array(
"name" => "MongoDB",
"type" => "database",
"count" => 1,
"info" => (object)array( "x" => 203, "y" => 102),
"versions" => array("0.9.7", "0.9.8", "0.9.9")
);
?>
]]>
</programlisting>
</example>
<para>
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: <literal>0, 1, 4, 5</literal>).
</para>
<para>
To insert this document, use <function>MongoCollection::insert</function>:
</para>
<example xml:id="mongo.tutorial.insert-example-2">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
$collection->insert( $doc );
?>
]]>
</programlisting>
</example>
<section xml:id="mongo.tutorial.insert.seealso">
<title>See Also</title>
<para>
The API documentation on <function>MongoCollection::insert</function>
contains more information about inserting data.
</para>
</section>
</section>
<section xml:id="mongo.tutorial.findone">
<title>
Finding Documents using <function>MongoCollection::findOne</function>
</title>
<para>
To show that the document we inserted in the previous step is stored in
the database, we can do a simple
<function>MongoCollection::findOne</function> 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.
</para>
<example xml:id="mongo.tutorial.findone-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
$document = $collection->findOne();
var_dump( $document );
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(6) {
["_id"]=>
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"
}
}
]]>
</screen>
</example>
<para>
Note that there is an <literal>_id</literal> field that has been added
automatically to your document. <literal>_id</literal> is the "primary key"
field. If your document does not specify one, the driver will add one
automatically.
</para>
<para>
If you specify your own <literal>_id</literal> field, it must be unique to
the collection. See the example here:
</para>
<example xml:id="mongo.tutorial.findone-example-2">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$db = $connection->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));
?>
]]>
</programlisting>
</example>
<para>
By default the driver will ensure the server has acknowledged the write
before returning. You can optionally turn this behaviour off by passing
<literal>array("w" => 0)</literal> 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 <literal>_id</literal> exception.
</para>
<section xml:id="mongo.tutorial.findone.seealso">
<title>See Also</title>
<para>
<function>MongoCollection::findOne</function> for more information about
finding data.
</para>
<para>
<classname>MongoId</classname> goes into more detail on unique ids.
</para>
<para>
The <link linkend="mongo.writes">writes</link> section covers
writes in more depth, and the <xref linkend="mongo.writeconcerns" />
chapter goes into details of the various Write Concern options.
</para>
</section>
</section>
<section xml:id="mongo.tutorial.insert.multiple">
<title>Adding Multiple Documents</title>
<para>
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
<literal>array( "i" => <replaceable>value</replaceable> );</literal> and we
can do this fairly efficiently in a loop:
</para>
<example xml:id="mongo.tutorial.insert.multiple-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
for ( $i = 0; $i < 100; $i++ )
{
$collection->insert( array( 'i' => $i, "field{$i}" => $i * 2 ) );
}
?>
]]>
</programlisting>
</example>
<para>
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
<literal>i</literal> field, but also a field name in the form of
<literal>field</literal> + <literal>$i</literal>.
</para>
</section>
<section xml:id="mongo.tutorial.counting">
<title>Counting Documents in A Collection</title>
<para>
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
<function>MongoCollection::count</function> method.
<example xml:id="mongo.tutorial.counting-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
echo $collection->count();
?>
]]>
</programlisting>
</example>
and it should print 101.
</para>
</section>
<section xml:id="mongo.tutorial.cursor">
<title>Using a Cursor to Get All of the Documents</title>
<para>
In order to get all the documents in the collection, we will use
<function>MongoCollection::find</function>. The find() method returns a
<classname>MongoCursor</classname> 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:
<example xml:id="mongo.tutorial.cursor-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
$cursor = $collection->find();
foreach ( $cursor as $id => $value )
{
echo "$id: ";
var_dump( $value );
}
?>
]]>
</programlisting>
</example>
and that should print all 101 documents in the collection.
<literal>$id</literal> is the <literal>_id</literal> field of a document
(cast to a string) and <literal>$value</literal> is the document itself.
</para>
<section xml:id="mongo.tutorial.cursor.seealso">
<title>See Also</title>
<para>
The API documentation on <function>MongoCollection::find</function>
contains more information about finding data.
</para>
</section>
</section>
<section xml:id="mongo.tutorial.criteria">
<title>Setting Criteria for a Query</title>
<para>
We can create a query to pass to the
<function>MongoCollection::find</function> 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 <literal>"i"</literal> field is
<literal>71</literal>, we would do the following:
</para>
<example xml:id="mongo.tutorial.criteria-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
$query = array( 'i' => 71 );
$cursor = $collection->find( $query );
while ( $cursor->hasNext() )
{
var_dump( $cursor->getNext() );
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(2) {
["_id"]=>
object(MongoId)#6 (0) {
}
["i"]=>
int(71)
["_ns"]=>
"testCollection"
}
]]>
</screen>
</example>
</section>
<section xml:id="mongo.tutorial.multi.query">
<title>Getting A Set of Documents With a Query</title>
<para>
We can use the query to get a set of documents from our collection. For
example, if we wanted to get all documents where <literal>"i"</literal>
&gt; <literal>50</literal>, we could write:
</para>
<example xml:id="mongo.tutorial.multi.query-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
$query = array( "i" => array( '$gt' => 50 ) ); //note the single quotes around '$gt'
$cursor = $collection->find( $query );
while ( $cursor->hasNext() )
{
var_dump( $cursor->getNext() );
}
?>
]]>
</programlisting>
<para>
which should print the documents where <literal>"i"</literal> &gt;
<literal>50</literal>. We could also get a range, say
<literal>20 &lt; i &lt;= 30</literal>:
</para>
<screen>
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
$query = array( 'i' => array( '$gt' => 20, "\$lte" => 30 ) );
$cursor = $collection->find( $query );
while ( $cursor->hasNext() )
{
var_dump( $cursor->getNext() );
}
?>
]]>
</screen>
</example>
<para>
Remember to always escape the $-symbol or use single quotes. Otherwise PHP
will interpret it to be the variable <varname>$gt</varname>.
</para>
</section>
<section xml:id="mongo.tutorial.indexes">
<title>Creating An Index</title>
<para>
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:
</para>
<example xml:id="mongo.tutorial.indexes-example">
<programlisting role="php">
<![CDATA[
<?php
$connection = new MongoClient();
$collection = $connection->database->collectionName;
$collection->ensureIndex( array( "i" => 1 ) ); // create index on "i"
$collection->ensureIndex( array( "i" => -1, "j" => 1 ) ); // index on "i" descending, "j" ascending
?>
]]>
</programlisting>
</example>
<para>
Indexing is critical for good read performance as your data grows. If you
are not familiar with indexing, check out the
<function>MongoCollection::ensureIndex</function> documentation and the core
<link xlink:href="&url.mongodb.dochub.indexes;">MongoDB indexing documentation</link>.
</para>
</section>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->