Querying
 
  Distributing queries to secondaries
  
   All queries (reads and writes) are only sent to the primary member of a
   replica set by default. This is however easily configurable by using the
   Read Preferences which allow
   you to set some generic read preferences (such as allowing secondary reads
   of the nearest server), and also provide ways to specifically target a
   server in a specific country, datacenter, or even hardware, by the use of
   replica set tag sets.
  
  
   Read preferences can be configured at every level of the driver:
   
   Each class inherits its read preference setting from the "parent" context.
  
  
   Example #1 Inheriting read preferences from the database level down to the cursor
   
<?php
$db->setReadPreference(MongoClient::RP_SECONDARY_PREFERRED);
$c = $db->myCollection;
$cursor = $c->find();
?>
    
   
  
   In this example, the the query will be executed against a secondary. The
   collection inherits MongoClient::RP_SECONDARY_PREFERRED
   from the database and the cursor inherits it from the collection.
  
  
  
   How secondaries are chosen
   
    Each instance of MongoClient chooses its own
    secondary using the available secondary 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:
   
   
    
<?php
$options = array("replicaSet" => "setName", "readPreference" => MongoClient::RP_SECONDARY_PREFERRED);
// on the Australian client
$m = new MongoClient("mongodb://primary,australianhost.secondary,europeanhost.secondary", $options);
$cursor = $m->foo->bar->find();
$cursor->getNext();
echo "Reading from: ", $cursor->info()["server"], "\n";
// on the European client
$m = new MongoClient("mongodb://primary,australianhost.secondary,europeanhost.secondary", $options);
$cursor = $m->foo->bar->find();
$cursor->getNext();
echo "Reading from: ", $cursor->info()["server"], "\n";
?>
     
    
    
Reading from: australianHost
Reading from: europeanHost
 
    
     Note that we have to do a query before a secondary is chosen: secondaries
     are chosen lazily by the driver, and for each query separately.
    
 
   
    You can see what the driver thinks is the current status of the set
    members by running MongoClient::getHosts() or
    MongoClient::getConnections().
   
   
    If no secondary is readable, the driver will send reads to the
    primary as we specified
    MongoClient::RP_SECONDARY_PREFERRED which will
    fallback to execute a query on a primary if no secondaries are available.
    A server is considered readable if its state is 2 (SECONDARY) and its
    health is 1.  You can check this with
    MongoClient::getHosts() and
    MongoClient::getConnections().
   
   
  
   Random notes
   
    Writes are always sent to the primary—and by default all reads are sent
    to the primary too.
   
   
 
  Querying by _id
  
   Every object inserted is automatically assigned a unique
   _id field, which is often a useful field to use in
   queries. This works similarly to "get last insert ID" functionality, except
   that the _id is chosen by the client.
  
  
   Suppose that we wish to find the document we just inserted.  Inserting adds
   an _id field to the document, so we can query by that:
   
    
<?php
$person = array("name" => "joe");
$people->insert($person);
// now $joe has an _id field
$joe = $people->findOne(array("_id" => $person['_id']));
?>
     
    
  
  
   Unless the user has specified otherwise, the _id field is a
   MongoId.  The most common mistake is attempting to use
   a string to match a MongoId.  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:
   
    
<?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));
?>
     
    
  
  
 
  Arrays
  
   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.
  
  
   For instance, if you want to save a list of awards in a document, you could
   say:
  
  
   
<?php
$collection->save(array("awards" => array("gold", "silver", "bronze")));
?>
    
   
  
   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:
  
  
{ "_id" : ObjectId("4b06c282edb87a281e09dad9"), "awards" : ["gold", "silver", "bronze"]}
 
  
   This can be done with a simple query, ignoring the fact that "awards" is an
   array:
  
   
    
<?php
  $cursor = $collection->find(array("awards" => "gold"));
?>
    
   
  
   Suppose we are querying for a more complex object, if each element of the
   array were an object itself, such as:
  
  
{
     "_id" : ObjectId("4b06c282edb87a281e09dad9"),
     "awards" :
     [
        {
            "first place" : "gold"
        },
        {
            "second place" : "silver"
        },
        {
            "third place" :  "bronze"
        }
     ]
}
 
  
   Still ignoring that this is an array, we can use dot notation to query the
   subobject:
  
   
    
<?php
$cursor = $collection->find(array("awards.first place" => "gold"));
?>
    
   
  
   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).
  
  
   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:
  
  
   
<?php
$cursor = $collection->find(array("awards" => array('$in' => array("gold", "copper"))));
?>