Nota: 1.1.0+
Si se está utilizando un » conjunto de réplicas y un driver versión 1.1.0 o superior, éste puede hacer que senvíen las consultas automáticamente a los esclavos. Este comportamiento no existe en las versiones anteriores del driver y no puede ser usado en un maestro-esclavo "normal".
Por omisión, el driver enviará todas las consultas al maestro. Si se habilita la opción "slaveOkay", el driver enviará todas las consultas a un servidor no primario, siempre y cuando fuera posible. La opción "slaveOkay" puede habilitarse a cualquier "nivel": conexión, base de datos, colección, y cursor. Cada clase hereda el ajuste "slaveOkay" de su clase superior, de modo que si hiciéramos:
<?php
$db->setSlaveOkay(true);
$c = $db->myCollection;
$cursor = $c->find();
?>
la consulta se ejecutaría contra un esclavo (la colección hereda "slaveOkay" de la base de datos y el cursor lo hereda de la colección).
Cada instancia de Mongo escoge su propio esclavo utilizando el esclavo disponible con el menor tiempo de respuesta. Es decir, si tuviéramos un cliente PHP en Europa y otro en Australia y tuviéramos un secundario en cada uno de estos centros de datos, podríamos:
<?php
// P es el primario
// en el cliente de Australia
$m1 = new Mongo("mongodb://P", array("replicaSet" => true));
$m1->foo->bar->find()->slaveOkay()->getNext();
echo "el esclavo de m1 es ".$m1->getSlave()."\n";
// en el cliente de Europa
$m2 = new Mongo("mongodb://P", array("replicaSet" => true));
$m2->foo->bar->find()->slaveOkay()->getNext();
echo "el esclavo de m2 es ".$m2->getSlave()."\n";
?>
probablemente se termine con algo así:
Tenga en cuenta que se debe realiza una consulta antes de elegir un esclavo: los esclavos
se eligen de forma tardía por el driver. Mongo::getSlave() devolverá
NULL
hasta que se utilice un esclavo.
Puede consultarse el estado actual del conjunto de miembros que ve el servidor ejecutando Mongo::getHosts().
Si no pudiera leerse ningun servidor no primario, el driver enviaría la lectura al primario (incluso con "slaveOkay" habilitado). Un servidor se considera legible si su estado es 2 (SECONDARY) y su salud es 1. Puede comprobarse esto con Mongo::getHosts().
Si disfruta tocando botones que probablemente no debería tocar, puede solicitar al driver un nuevo esclavo usando Mongo::switchSlave(). Esto escogería un nuevo esclavo (si hubiera alguno disponible), pero no debería usarse salvo que se sepa bien qué se está haciendo.
Las escrituras siempre se envian al primario. Los comandos de la base de datos, incluso los comandos de sólo lectura, también se envían siempre al primario.
La salud y estado de un esclavo se comprueba cada 5 secundos o al realizarse la siguiente operación antes de que venzan los 5 segundos. También se volverá a comprobar la configuración cuando el driver tenga problemas accediendo a algún servidor.
Tenga en cuenta que un servidor no primario podría encontrarse detrás de un primario en las operaciones, por lo que su software deberá tolerar datos "desfasados" (o si no tendrá que usar w en todas las escrituras).
A cada objeto que se inserta se le asigna automáticamente un campo _id único, a menudo útil para usar en consultas.
Supongamos que queremos localizar el documento que acabamos de insertar. Las inserciones añaden un campo _id al documento, de modo que podemos consultar en base a él:
<?php
$person = array("name" => "joe");
$people->insert($person);
// ahora $joe tiene un campo _id
$joe = $people->findOne(array("_id" => $person['_id']));
?>
Salvo que se indique lo contrario, el campo _id será de tipo MongoId. El error más frecuente consiste en usar una cadena de texto que concuerde con un MongoId. Debe tenerse presente que son dos tipos de datos distintos, y no concuerdan, del mismo modo que el texto "array()" no es lo mismo que un array vacío. Por ejemplo:
<?php
$person = array("name" => "joe");
$people->insert($person);
// convertimos el _id a texto
$pid = $person['_id'] . "";
// FALLO - $pid es un texto, no un MongoId
$joe = $people->findOne(array("_id" => $pid));
?>
Los arrays son especiales por varias razones. En primer lugar, hay dos tipos de arrays que MongoDB utiliza: arrays "normales" y arrays asociativos. Los arrays asociativos pueden tener cualquier combinación de claves y valores. Los arrays "normales" se definen como arrays con un índice numérico ascendente que comienza por 0 y se incrementa en uno por cada elemento. Estos son, normalmente, los arrays de PHP más comunes.
Por ejemplo, si se quisiera guardar una lista de premios en un documento, podríamos poner:
<?php
$collection->save(array("awards" => array("gold", "silver", "bronze")));
?>
Las consultas pueden llegar hasta los arrays en busca de elementos. Supongamos que queremos encontrar todos los documentos que contienen un elemento de un array con un determinado valor. Por ejemplo, documentos con un premio "gold", como por ejemplo:
{ "_id" : ObjectId("4b06c282edb87a281e09dad9"), "awards" : ["gold", "silver", "bronze"]}
Esto puede lograrse con una única consulta, ignorando el hecho de que "awards" es un array:
<?php
$cursor = $collection->find(array("awards" => "gold"));
?>
Supongamos que estamos consultando un objeto más complejo, si cada elemento del array fuera un objeto en sí mismo, como en:
{ "_id" : ObjectId("4b06c282edb87a281e09dad9"), "awards" : [ { "first place" : "gold" }, { "second place" : "silver" }, { "third place" : "bronze" } ] }
Incluso aquí, ignorando que se trata de un array, podemos usar la misma notación para consultar al subobjeto:
<?php
$cursor = $collection->find(array("awards.first place" => "gold"));
?>
Debe tenerse en cuenta que no importa que haya espacios en los nombres de campos (pese a que sea mejor no usarlos, sólo por mantenerlo más legible).
Puede también usarse un array para consultar un determinado número de posibles valores. Por ejemplo, si buscáramos documentos "gold" o "copper", podríamos hacer:
<?php
$cursor = $collection->find(array("awards" => array('$in' => array("gold", "copper"))));
?>