mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-22 11:58:55 +00:00

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@313052 c90b9560-bf6c-de11-be94-00142212c4b1
325 lines
8.2 KiB
XML
325 lines
8.2 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<section xml:id="mongo.queries" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Querying</title>
|
|
|
|
<section>
|
|
<title>Distributing queries to slaves</title>
|
|
|
|
<note>
|
|
<title>1.1.0+</title>
|
|
<para>
|
|
If you are using a
|
|
<link xlink:href="&url.mongodb.replica;">replica set</link> and version
|
|
1.1.0 or above of the driver, the driver can automatically route reads to
|
|
slaves. This behavior does not exist in earlier versions of the driver and
|
|
<emphasis>cannot</emphasis> be used with "normal" master-slave.
|
|
</para>
|
|
</note>
|
|
|
|
<para>
|
|
By default, the driver will send all queries to the master. If you set the
|
|
"slaveOkay" option, the driver will send all queries to a non-primary server,
|
|
if possible. The "slaveOkay" option can be set at every "level":
|
|
<link linkend="mongo.setslaveokay">connection</link>,
|
|
<link linkend="mongodb.setslaveokay">database</link>,
|
|
<link linkend="mongocollection.setslaveokay">collection</link>, and
|
|
<link linkend="mongocursor.slaveokay">cursor</link>. Each class inherits the
|
|
"slaveOkay" setting from the class above it, so if you do:
|
|
</para>
|
|
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$db->setSlaveOkay(true);
|
|
$c = $db->myCollection;
|
|
|
|
$cursor = $c->find();
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
|
|
<para>
|
|
then the query will be executed against a slave (the collection inherited
|
|
"slaveOkay" from the database and the cursor inherited it from the
|
|
collection).
|
|
</para>
|
|
|
|
<section>
|
|
<title>How slaves are chosen</title>
|
|
|
|
<para>
|
|
Each instance of <classname>Mongo</classname> chooses its own slave using
|
|
the available slave with the lowest ping time. So, if we had a PHP client
|
|
in Europe and one in Australia and we had one secondary in each of these
|
|
data centers, we could do:
|
|
</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// P is the primary
|
|
|
|
// on the Australian client
|
|
$m1 = new Mongo("mongodb://P", array("replicaSet" => true));
|
|
$m1->foo->bar->find()->slaveOkay()->getNext();
|
|
echo "m1's slave is ".$m1->getSlave()."\n";
|
|
|
|
// on the European client
|
|
$m2 = new Mongo("mongodb://P", array("replicaSet" => true));
|
|
$m2->foo->bar->find()->slaveOkay()->getNext();
|
|
echo "m2's slave is ".$m2->getSlave()."\n";
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
<para>
|
|
we'd probably end up with something like:
|
|
</para>
|
|
<screen>
|
|
m1's slave is: australianHost
|
|
m2's slave is: europeanHost
|
|
</screen>
|
|
|
|
<para>
|
|
Note that we have to do a query before a slave is chosen: slaves are chosen
|
|
lazily by the driver. <function>Mongo::getSlave</function> will return
|
|
&null; until a slave is used.
|
|
</para>
|
|
|
|
<para>
|
|
You can see what the driver thinks is the current status of the set members
|
|
by running <function>Mongo::getHosts</function>.
|
|
</para>
|
|
|
|
<para>
|
|
If no non-primary server is readable, the driver will send
|
|
reads to the primary (even if "slaveOkay" is set). A server is considered
|
|
readable if its state is 2 (SECONDARY) and its health is 1. You can check
|
|
this with <function>Mongo::getHosts</function>.
|
|
</para>
|
|
|
|
<para>
|
|
If you enjoy twiddling knobs that you probably shouldn't mess with, you can
|
|
request the driver to use a different slave by calling
|
|
<function>Mongo::switchSlave</function>. This may choose a new slave
|
|
(if one is available) and shouldn't be used unless you know what you're
|
|
doing.
|
|
</para>
|
|
|
|
</section>
|
|
<section>
|
|
<title>Random notes</title>
|
|
|
|
<para>
|
|
Writes are always sent to the primary. Database commands, even read-only
|
|
commands, are also always sent to the primary.
|
|
</para>
|
|
|
|
<para>
|
|
The health and state of a slave is checked every 5 seconds or when the next
|
|
operation occurs after 5 seconds. It will also recheck the configuration
|
|
when the driver has a problem reaching a server.
|
|
</para>
|
|
|
|
<para>
|
|
Note that a non-primary server may be behind the primary in operations, so
|
|
your application must be okay with getting out-of-date data (or you must use
|
|
w for all writes).
|
|
</para>
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<title>Querying by _id</title>
|
|
<para>
|
|
Every object inserted is automatically assigned a unique _id field, which is
|
|
often a useful field to use in queries.
|
|
</para>
|
|
<para>
|
|
Suppose that we wish to find the document we just inserted. Inserting adds
|
|
and _id field to the document, so we can query by that:
|
|
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$person = array("name" => "joe");
|
|
|
|
$people->insert($person);
|
|
|
|
// now $joe has an _id field
|
|
$joe = $people->findOne(array("_id" => $person['_id']));
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
Unless the user has specified otherwise, the _id field is a
|
|
<classname>MongoId</classname>. The most common mistake is attepting to use
|
|
a string to match a <classname>MongoId</classname>. Keep in mind that these
|
|
are two different datatypes, and will not match each other in the same way
|
|
that the string "array()" is not the same as an empty array. For example:
|
|
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$person = array("name" => "joe");
|
|
|
|
$people->insert($person);
|
|
|
|
// convert the _id to a string
|
|
$pid = $person['_id'] . "";
|
|
|
|
// FAILS - $pid is a string, not a MongoId
|
|
$joe = $people->findOne(array("_id" => $pid));
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Arrays</title>
|
|
|
|
<para>
|
|
Arrays are special in a couple ways. First, there are two types that
|
|
MongoDB uses: "normal" arrays and associative arrays. Associative arrays can
|
|
have any mix of key types and values. "Normal" arrays are defined as arrays
|
|
with ascending numeric indexes starting at 0 and increasing by one for each
|
|
element. These are, typically, just your usual PHP array.
|
|
</para>
|
|
|
|
<para>
|
|
For instance, if you want to save a list of awards in a document, you could
|
|
say:
|
|
</para>
|
|
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$collection->save(array("awards" => array("gold", "silver", "bronze")));
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
|
|
<para>
|
|
Queries can reach into arrays to search for elements. Suppose that we wish
|
|
to find all documents with an array element of a given value. For example,
|
|
documents with a "gold" award, such as:
|
|
</para>
|
|
|
|
<programlisting>
|
|
<![CDATA[
|
|
{ "_id" : ObjectId("4b06c282edb87a281e09dad9"), "awards" : ["gold", "silver", "bronze"]}
|
|
]]>
|
|
</programlisting>
|
|
|
|
<para>
|
|
This can be done with a simple query, ignoring the fact that "awards" is an
|
|
array:
|
|
</para>
|
|
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$cursor = $collection->find(array("awards" => "gold"));
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
|
|
<para>
|
|
Suppose we are querying for a more complex object, if each element of the
|
|
array were an object itself, such as:
|
|
</para>
|
|
|
|
<programlisting>
|
|
<![CDATA[
|
|
{
|
|
"_id" : ObjectId("4b06c282edb87a281e09dad9"),
|
|
"awards" :
|
|
[
|
|
{
|
|
"first place" : "gold"
|
|
},
|
|
{
|
|
"second place" : "silver"
|
|
},
|
|
{
|
|
"third place" : "bronze"
|
|
}
|
|
]
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
|
|
<para>
|
|
Still ignoring that this is an array, we can use dot notation to query the
|
|
subobject:
|
|
</para>
|
|
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$cursor = $collection->find(array("awards.first place" => "gold"));
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
|
|
<para>
|
|
Notice that it doesn't matter that there is a space in the field name
|
|
(although it may be best not to use spaces, just to make things more
|
|
readable).
|
|
</para>
|
|
|
|
<para>
|
|
You can also use an array to query for a number of possible values. For
|
|
instance, if we were looking for documents "gold" or "copper", we could do:
|
|
</para>
|
|
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$cursor = $collection->find(array("awards" => array('$in' => array("gold", "copper"))));
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
|
|
</section>
|
|
</section>
|
|
|
|
<!-- 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
|
|
-->
|
|
|