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 du driver.
- Sous la forme d'un paramètre ou d'une option à MongoClient::__construct()
- Spécifiquement, en appelant la méthode MongoClient::setReadPreference()
- Au niveau de la base de données, avec la méthode MongoDB::setReadPreference()
- Au niveau de la collection, avec la méthode MongoCollection::setReadPreference()
- Au niveau du curseur, avec la méthode MongoCursor::setReadPreference() ou la méthode MongoCommandCursor::setReadPreference()
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();
?>
Dans cet exemple, 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";
?>
L'exemple ci-dessus va afficher quelque chose de similaire à :
Lecture depuis : australianHost Lecture depuis : europeanHost
Notez que nous devons exécuter une requête avant qu'un secondaire ne soit choisi : les secondaires sont choisis par le driver et pour chaque requête, séparément.
Vous pouvez voir le choix du driver, en analysant le statut courant du membres du jeu, en exécutant la méthode MongoClient::getHosts() ou la méthode MongoClient::getConnections().
Si aucun secondaire n'est lisible, le driver enverra les lectures au primaire,
tel que nous l'avons spécifié avec
MongoClient::RP_SECONDARY_PREFERRED
, qui aura comme comportement
de repli que d'exécuter une requete sur un primaire, si aucune secondaire n'est
disponible. Un serveur est considéré comme lisible si son état vaut 2 (secondaire)
et sa santé vaut 1. Vous pouvez vérifier cela avec les méthodes
MongoClient::getHosts() et
MongoClient::getConnections().
Diverses notes
Les écritures sont toujours envoyées au serveur principal et par défaut, toutes les lectures sont aussi envoyées au primaire.
Interrogation sur un _id
Chaque objet inséré se voit assigné automatiquement un champ unique _id, qui est bien utile pour être utilisé dans les requêtes. Ceci fonctionne de façon similaire à la fonctionalité "donne moi le dernier ID inséré", excepté que _id est choisi par le client.
Supposez que vous voulez trouver un document que vous venez tout juste d'insérer. L'insertion ajoute un champ _id au document, aussi, vous pouvez effectuer votre requête de la sorte :
<?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(). |
Document créé le 30/01/2003, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/php-rf-mongo.queries.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.
Références
Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.