Firestore en mode Datastore permet d'utiliser des filtres de plage et d'inégalité sur plusieurs propriétés dans une seule requête. Cette fonctionnalité vous donne des conditions de plage et d'inégalité sur plusieurs propriétés et simplifie le développement de votre application en déléguant l'implémentation du post-filtrage vers 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 qui doivent être terminées en moins de 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 concernant l'indexation
Avant de commencer à exécuter des requêtes, assurez-vous d'avoir lu sur les requêtes.
Si aucune clause ORDER BY
n'est spécifiée, Firestore en mode Datastore utilise un index qui
peuvent satisfaire à la condition de filtre de la requête
pour la traiter. Cette approche produit un ensemble de résultats ordonnés selon la définition de l'index.
Pour optimiser les performances et les coûts des requêtes Firestore en mode Datastore, optimiser l'ordre des propriétés dans l'index. Pour ce faire, assurez-vous que est ordonné de gauche à droite, de sorte que la requête aboutisse qui empêche l'analyse des entrées d'index superflues.
Par exemple, supposons que vous souhaitiez rechercher dans une collection d'employés ceux dont le salaire est supérieur à 100 000 $ et dont le nombre d'années d'expérience est supérieur à 0. D'après votre compréhension du jeu de données, vous savez que la contrainte de salaire est plus sélective que la contrainte d'expérience. L'index (salary [...], experience [...])
est un index qui réduit le nombre d'analyses d'index. Par conséquent, une requête rapide et économique classe 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 l'optimisation des index
Lorsque vous optimisez des index, tenez compte des bonnes pratiques suivantes.
Classer les requêtes par égalités suivies de la plage la plus sélective ou du champ d'inégalité
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
les entrées d'index analysées par Firestore en mode Datastore. Firestore en mode Datastore utilise les propriétés restantes de l'index pour répondre aux 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
Firestore en mode Datastore analyse, mais filtre les entités sans correspondance afin que le nombre
le nombre d'entités renvoyées aux clients est réduit.
Pour en savoir plus sur la création d'index efficaces, consultez les sections Structure et définition des index et Optimiser les index.
Classer les propriétés par ordre décroissant de sélectivité de la contrainte de requête
Pour vous assurer que Firestore en mode Datastore sélectionne l'index optimal pour votre requête,
spécifier une clause orderBy()
qui ordonne les propriétés de plage et d'inégalité en fonction
sur le degré de sélectivité de leurs contraintes dans votre requête, en commençant par les
de façon sélective. Une sélectivité plus élevée correspond à moins d'entités, tandis qu'une sélectivité plus faible correspond à plus d'entités. Dans l'ordre d'indexation, placez les propriétés de plage et d'inégalité ayant une sélectivité plus élevée avant celles ayant une sélectivité plus faible.
Pour réduire le nombre d'entités que Firestore en mode Datastore analyse et renvoie sur le réseau, 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 si l'ensemble de résultats attendu est limité, vous pouvez implémenter une logique côté client pour commander à nouveau selon vos attentes.
Par exemple, si vous souhaitez rechercher dans une collection d'employés les employés basés aux États-Unis dont le salaire est supérieur à 100 000 $ et classer les résultats par année d'expérience de l'employé. Si vous prévoyez que seul un petit nombre d'employés auront un salaire supérieur à 100 000 $, voici un moyen 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`
Alors que l'ajout d'un tri sur experience
à la requête permet d'obtenir le même ensemble
et éviter 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, Firestore en mode Datastore préfère toujours un indice dont le préfixe de propriétés d'index correspond à la clause de tri de la requête. Si vous avez ajouté experience
à la clause order by :
Firestore en mode Datastore sélectionne alors l'index (experience [...], salary [...])
pour calculer les résultats d'une requête. Puisqu'il n'y a pas d'autres contraintes
experience
, Firestore en mode Datastore lira toutes les entrées d'index de la
employees
avant d'appliquer le filtre salary
pour trouver le résultat final
ensemble de résultats. Cela signifie que les entrées d'index qui ne répondent pas aux critères salary
sont tout de même 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 Tarifs.
Limites
En plus des limites des requêtes, veuillez noter les 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, 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 Firestore en mode Datastore utilise les index.