Interrogation

Distribution des requêtes aux secondaires

Toutes les requêtes (en lecture et en écriture) ne sont envoyées qu'au membre primaire du jeu de réplication par défaut. Ce comportement est cependant facilement configurable en utilisant les préférences de lecture qui vous permettent de définir quelques préférences de lecture génériques (comme l'autorisation des lectures sur un secondaire du serveur le plus proche), mais aussi fournissent une façon de spécifier un serveur précis, dans un pays spécifique, un centre de données précis, ou même un matériel donné, en utilisant les tags des jeux de réplication.

Les préférences de lecture peuvent être configurées à tous les niveaux.

Chaque classe hérite de la configuration des préférences de lecture de la classe sous-jacente, aussi, si vous faîtes :

Exemple #1 Héritage des préférences de lecture depuis le niveau de la base de données vers le curseur

<?php
$db->setReadPreference(MongoClient::RP_SECONDARY_PREFERRED);
$c = $db->myCollection;

$cursor = $c->find();
?>

alors, la requête sera exécutée sur un secondaire (la collection hérite de MongoClient::RP_SECONDARY_PREFERRED depuis la base de données, et le curseur en hérite de la collection).

Comment les secondaires sont-ils choisis ?

Chaque instance de MongoClient choisit son secondaire en utilisant le secondaire ayant le ping le moins élevé. Ainsi, si nous avons un client PHP en Europe et un en Australie et que nous avons un secondaire dans chacun de ces data-centers, nous pouvons faire :

<?php
$options = array("replicaSet" => "setName", "readPreference" => MongoClient::RP_SECONDARY_PREFERRED);

// sur un client Australien
$m = new MongoClient("mongodb://primary,australianhost.secondary,europeanhost.secondary", $options);
$cursor = $m->foo->bar->find();
$cursor->getNext();
echo "Lecture depuis : ", $cursor->info()["server"], "\n";

// sur un client européen
$m = new MongoClient("mongodb://primary,australianhost.secondary,europeanhost.secondary", $options);
$cursor = $m->foo->bar->find();
$cursor->getNext();
echo "Lecture depuis : ", $cursor->info()["server"], "\n";
?>
<?php
$person = array("name" => "joe");

$people->insert($person);

// Maintenant, $joe a un champ _id
$joe = $people->findOne(array("_id" => $person['_id']));
?>

Tant que l'utilisateur ne l'a pas spécifié autrement, le champ _id est un MongoId. L'erreur la plus courante est d'essayer d'utiliser une chaîne qui correspond à un MongoId. Gardez à l'esprit que cet identifiant a 2 types de données différents, et ne correspond pas l'un l'autre, de la même façon que la chaîne "array()" n'est pas la même chose qu'un tableau vide. Par exemple :

<?php
$person = array("name" => "joe");

$people->insert($person);

// Conversion de l'_id en une chaîne
$pid = $person['_id'] . "";

// ECHEC - $pid est une chaîne, et non un MongoId
$joe = $people->findOne(array("_id" => $pid));
?>

Les tableaux

Les tableaux sont spéciaux à plus d'un titre. Tout d'abord, il y a 2 types utilisés par MongoDB : des tableaux "normaux" et des tableaux associatifs. Les tableaux associatifs peuvent avoir plusieurs types de clés et de valeurs. Les tableaux "normaux" sont définis comme tableaux dans ces indices numériques ascendants, en commençant par 0 et s'incrémentant de 1 pour chaque élément. Ces 2 types correspondent à ce que vous connaissez déjà comme type en PHP.

Actuellement, si vous voulez sauvegarder la liste des récompenses dans un document, vous pouvez :

<?php

$collection->save(array("awards" => array("gold", "silver", "bronze")));

?>

Les requêtes peuvent effectuer des recherches directement dans les éléments. Supposez que nous souhaitons trouver tous les documents dont l'élément du tableau est à une valeur fournie. Par exemple, les documents dont la récompense est l'or, comme ceci :

{ "_id" : ObjectId("4b06c282edb87a281e09dad9"), "awards" : ["gold", "silver", "bronze"]}

Ceci peut être effectué avec une requête simple, en ignorant le fait que "awards" est un tableau :

<?php

$cursor = $collection->find(array("awards" => "gold"));

?>

Supposez que vous interrogiez la base de données avec un objet plus complexe, dont chaque élément du tableau sont eux-mêmes des objets, comme ceci :

{ 
     "_id" : ObjectId("4b06c282edb87a281e09dad9"), 
     "awards" : 
     [
        {
            "first place" : "gold"
        },
        {
            "second place" : "silver" 
        },
        {
            "third place" :  "bronze"
        }
     ]
}

Continuons d'ignorer que c'est un tableau. Nous pouvons utiliser la notation basée sur les points pour interroger le sous-objet :

<?php

$cursor = $collection->find(array("awards.first place" => "gold"));

?>

Notez qu'il importe peu qu'il y ait un espace dans le nom du champ (bien qu'il convient de ne pas en mettre, juste pour rendre le code plus lisible).

Vous pouvez également utiliser un tableau contenant plusieurs valeurs à chercher. Actuellement, si nous cherchons les documents "gold" et "copper", nous pouvons le faire comme ceci :

<?php

$cursor = $collection->find(array("awards" => array('$in' => array("gold", "copper"))));

?>

Historique

Version Description
1.3.0 Introduction du framework pour les préférence de lecture permettant une contrôle fin des lectures sur les secondaires.
1.3.0 L'utilisation de slaveOkay devient obsolète ; l'alternative est les préférences de lecture.
1.1.0 Introduction de la possibilité de router les lectures vers les secondaires des membres du jeu de réplication, en utilisant la méthode Mongo::setSlaveOkay().
LoadingChargement en cours