Cloud Firestore en mode Datastore accepte l'utilisation de filtres de plage et d'inégalité sur plusieurs propriétés dans une seule requête. Cette fonctionnalité vous permet d'appliquer des conditions de plage et d'inégalité à plusieurs propriétés, et simplifie le développement de votre application en déléguant l'implémentation de la logique de post-filtrage à Cloud Firestore en mode Datastore.
Filtres de plage et d'inégalité sur plusieurs propriétés
La requête suivante utilise des filtres de plage sur la priorité et les jours pour renvoyer toutes les tâches dont la priorité est supérieure à quatre et dont le délai d'exécution est inférieur à trois jours.
Go
query := datastore.NewQuery("Task").
FilterField("priority", ">", 4).
FilterField("days", "<", 3).
GQL
SELECT * FROM /tasks WHERE priority > 4 AND days < 3;
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("Task")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("priority", 4), PropertyFilter.lt("days", 3)))
.build();
Node.js
const query = datastore
.createQuery('Task')
.filter(
and([
new PropertyFilter('priority', '>', 4),
new PropertyFilter('days', '<', 3),
])
);
Python
from google.cloud import datastore
client = datastore.Client()
query = client.query(kind="Task")
query.add_filter(filter=PropertyFilter("priority", ">", 4))
query.add_filter(filter=PropertyFilter("days", "<", 3))
PHP
$query = $datastore->query()
->kind('Task')
->filter('priority', '>', 4)
->filter('days', '<', 3)
C#
Query query = new Query("Task")
{
Filter = Filter.And(Filter.GreaterThan("priority", 4),
Filter.LessThan("days", 3))
};
Ruby
query = datastore.query("Task")
.where("priority", ">", 4)
.where("days", "<", 3)
Considérations relatives à l'indexation
Avant de commencer à exécuter des requêtes, assurez-vous de lire la section Requêtes.
Si aucune clause ORDER BY n'est spécifiée, Cloud Firestore en mode Datastore utilise n'importe quel index pouvant satisfaire la condition de filtre de la requête pour la traiter. Cette approche génère un ensemble de résultats trié en fonction de la définition de l'index.
Pour optimiser les performances et le coût des requêtes Cloud Firestore en mode Datastore, optimisez l'ordre des propriétés dans l'index. Pour ce faire, assurez-vous que votre index est trié de gauche à droite afin que la requête soit réduite à un ensemble de données qui empêche l'analyse des entrées d'index superflues.
Supposons, par exemple, que vous souhaitiez effectuer une recherche dans une collection d'employés pour trouver ceux qui travaillent aux États-Unis, dont le salaire est supérieur à 100 000 $ et qui ont plus de 0 an d'expérience. En fonction de votre compréhension de l'ensemble de données, vous savez que la contrainte de salaire est plus sélective que la contrainte d'expérience. Un index qui réduit le nombre d'analyses d'index est l'index (salary [...], experience [...]). Par conséquent, une requête rapide et économique trie salary avant experience, comme illustré dans l'exemple suivant :
GQL
SELECT *
FROM /employees
WHERE salary > 100000 AND experience > 0
ORDER BY salary, experience
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
.setOrderBy(OrderBy("salary"), OrderBy("experience"))
.build();
Node.js
const query = datastore
.createQuery("employees")
.filter(
and([
new PropertyFilter("salary", ">", 100000),
new PropertyFilter("experience", ">", 0),
])
)
.order("salary")
.order("experience");
Python
query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.add_filter("experience", ">", 0)
query.order = ["-salary", "-experience"]
Bonnes pratiques pour optimiser les index
Lorsque vous optimisez des index, tenez compte des bonnes pratiques suivantes.
Trier les requêtes par égalités, suivies du champ de plage ou d'inégalité le plus sélectif
Cloud Firestore en mode Datastore utilise les propriétés les plus à gauche d'un index composite pour satisfaire les contraintes d'égalité, ainsi que la contrainte de plage et d'inégalité, le cas échéant, sur le premier champ de la requête orderBy(). Ces contraintes peuvent réduire le nombre d'entrées d'index analysées par Cloud Firestore en mode Datastore. Cloud Firestore en mode Datastore utilise les propriétés restantes de l'index pour satisfaire les autres contraintes de plage et d'inégalité de la requête. Ces contraintes ne réduisent pas le nombre d'entrées d'index analysées par Cloud Firestore en mode Datastore, mais elles filtrent les entités non correspondantes afin de réduire le nombre d'entités renvoyées aux clients.
Pour en savoir plus sur la création d'index efficaces, consultez la section Structure et définition des index et Optimiser les index.
Trier les propriétés par ordre décroissant de sélectivité des contraintes de requête
Pour vous assurer que Cloud Firestore en mode Datastore sélectionne l'index optimal pour votre requête, spécifiez une clause orderBy() qui trie les propriétés de plage et d'inégalité en fonction de la sélectivité de leurs contraintes dans votre requête, en commençant par la plus sélective. Une sélectivité plus élevée correspond à moins d'entités, tandis qu'une sélectivité plus faible correspond à davantage d'entités. Dans votre ordre d'indexation, placez les propriétés de plage et d'inégalité avec une sélectivité plus élevée avant celles avec une sélectivité plus faible.
Pour minimiser le nombre d'entités analysées et renvoyées sur le réseau par Cloud Firestore en mode Datastore, vous devez toujours trier les propriétés par ordre décroissant de sélectivité des contraintes de requête. Si l'ensemble de résultats n'est pas dans l'ordre requis et qu'il est censé être petit, vous pouvez implémenter une logique côté client pour le réorganiser selon vos attentes.
Par exemple, si vous souhaitez effectuer une recherche dans une collection d'employés pour trouver ceux qui travaillent aux États-Unis,dont le salaire est supérieur à 100 000 $ et trier les résultats par année d'expérience de l'employé. Si vous vous attendez à ce qu'un petit nombre d'employés aient un salaire supérieur à 100 000 $, voici une façon efficace d'écrire la requête :
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(PropertyFilter.gt("salary", 100000))
.setOrderBy(OrderBy("salary"))
.build();
QueryResults<Entity> results = datastore.run(query);
// Order results by `experience`
Node.js
const query = datastore
.createQuery("employees")
.filter(new PropertyFilter("salary", ">", 100000))
.order("salary");
const [entities] = await datastore.runQuery(query);
// Order results by `experience`
Python
query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.order = ["salary"]
results = query.fetch()
// Order results by `experience`
Bien que l'ajout d'un ordre sur experience à la requête génère le même ensemble d'entités et évite de réorganiser les résultats sur les clients, la requête peut lire beaucoup plus d'entrées d'index superflues que la requête précédente. En effet, Cloud Firestore en mode Datastore préfère toujours un index dont le préfixe des propriétés d'index correspond à la clause "order by" de la requête. Si experience était ajouté à la clause "order by",
Cloud Firestore en mode Datastore sélectionnerait l'index (experience [...], salary [...])
pour calculer les résultats de la requête. Comme il n'existe aucune autre contrainte sur experience, Cloud Firestore en mode Datastore lira toutes les entrées d'index de la collection employees avant d'appliquer le filtre salary pour trouver l'ensemble de résultats final. Cela signifie que les entrées d'index qui ne satisfont pas le filtre salary sont toujours lues, ce qui augmente la latence et le coût de la requête.
Tarifs
Les requêtes avec des filtres de plage et d'inégalité sur plusieurs propriétés sont facturées en fonction des entités lues et des entrées d'index lues.
Pour en savoir plus, consultez la page des tarifs.
Limites
Outre les limites des requêtes, tenez compte des limites suivantes avant d'utiliser des requêtes avec des filtres de plage et d'inégalité sur plusieurs propriétés :
- Pour éviter que les requêtes ne deviennent trop coûteuses à exécuter, Cloud Firestore en mode Datastore limite le nombre d'opérateurs de plage ou d'inégalité à 10.
Étape suivante
- Découvrez comment optimiser vos requêtes.
- Découvrez comment effectuer des requêtes simples et composées.
- Découvrez comment Cloud Firestore en mode Datastore utilise les index.