Arrière-plan
Les opérations de pipeline fournissent une nouvelle interface de requête pour
Cloud Firestore qui est compatible avec les fonctionnalités de requête avancées et les expressions complexes. Elle introduit de nombreuses fonctions, y compris min(...), max(...), substring(...), regex_match(...) et array_contains_all(...), ainsi que des étapes permettant d'effectuer des transformations complexes.
Premiers pas
Pour installer et initialiser les SDK clients, consultez les instructions des guides suivants :
Syntaxe
Les sections suivantes offrent un aperçu de la syntaxe des opérations de pipeline.
Concepts
Une différence notable avec les opérations de pipeline est l'introduction d'un ordre "d'étape" explicite. Cela permet d'exprimer des requêtes plus complexes. Toutefois, il s'agit d'une différence notable par rapport à l'interface de requête existante utilisant des opérations de base, où l'ordre des étapes était implicite. Considérez l'exemple d'opérations de pipeline suivant :
Web
const pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the // pipeline would have unintentional results. .limit(10);
Swift
let pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(Field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort([Field("name").ascending()]) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10)
Kotlin
val pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10)
Java
Pipeline pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10);
Python
from google.cloud.firestore_v1.pipeline_expressions import Field pipeline = ( client.pipeline() .collection("cities") .where(Field.of("population").greater_than(100_000)) .sort(Field.of("name").ascending()) .limit(10) )
Initialisation
Les opérations de pipeline ont une syntaxe très familière provenant des requêtes Cloud Firestore existantes. Pour commencer, initialisez une requête en écrivant ce qui suit :
Web
const { getFirestore } = require("firebase/firestore"); const { execute } = require("firebase/firestore/pipelines"); const database = getFirestore(app, "enterprise"); const pipeline = database.pipeline();
Swift
let firestore = Firestore.firestore(database: "enterprise") let pipeline = firestore.pipeline()
Kotlin
val firestore = Firebase.firestore("enterprise") val pipeline = firestore.pipeline()
Java
FirebaseFirestore firestore = FirebaseFirestore.getInstance("enterprise"); PipelineSource pipeline = firestore.pipeline();
Python
firestore_client = firestore.client(default_app, "your-new-enterprise-database") pipeline = firestore_client.pipeline()
Structure
Plusieurs termes sont importants à comprendre lors de la création d'opérations de pipeline : les étapes, les expressions et les fonctions.

Étapes : un pipeline peut comporter une ou plusieurs étapes. Logiquement, elles représentent la série d'étapes nécessaires à l'exécution de la requête. Remarque : En pratique, les étapes peuvent être exécutées dans le désordre pour améliorer les performances. Toutefois, cela ne modifie pas l'intention ni l'exactitude de la requête.
Expressions : les étapes acceptent souvent une expression qui vous permet d'exprimer des requêtes plus complexes. L'expression peut être simple et se composer d'une seule fonction, comme eq("a", 1). Vous pouvez également exprimer des expressions plus complexes en imbriquant des expressions comme and(eq("a", 1), eq("b", 2)).
Références de champ et références constantes
Les opérations de pipeline sont compatibles avec les expressions complexes. Par conséquent, il peut être nécessaire de déterminer si une valeur représente un champ ou une constante. Prenons l'exemple suivant :
Web
const pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")));
Swift
let pipeline = db.pipeline() .collection("cities") .where(Field("name").equal(Constant("Toronto")))
Kotlin
val pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")))
Java
Pipeline pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")));
Python
from google.cloud.firestore_v1.pipeline_expressions import Field, Constant pipeline = ( client.pipeline() .collection("cities") .where(Field.of("name").equal(Constant.of("Toronto"))) )
Étapes
Étapes d'entrée
L'étape d'entrée représente la première étape d'une requête. Elle définit l'ensemble initial de documents sur lesquels vous effectuez une requête. Pour les opérations de pipeline, cela est en grande partie semblable aux requêtes existantes, où la plupart des requêtes commencent par une étape collection(...) ou collection_group(...). Deux nouvelles étapes d'entrée sont database() et documents(...), où database() permet de renvoyer tous les documents de la base de données, tandis que documents(...) agit de la même manière qu'une lecture par lot.
Web
let results; // Return all restaurants in San Francisco results = await execute(db.pipeline().collection("cities/sf/restaurants")); // Return all restaurants results = await execute(db.pipeline().collectionGroup("restaurants")); // Return all documents across all collections in the database (the entire database) results = await execute(db.pipeline().database()); // Batch read of 3 documents results = await execute(db.pipeline().documents([ doc(db, "cities", "SF"), doc(db, "cities", "DC"), doc(db, "cities", "NY") ]));
Swift
var results: Pipeline.Snapshot // Return all restaurants in San Francisco results = try await db.pipeline().collection("cities/sf/restaurants").execute() // Return all restaurants results = try await db.pipeline().collectionGroup("restaurants").execute() // Return all documents across all collections in the database (the entire database) results = try await db.pipeline().database().execute() // Batch read of 3 documents results = try await db.pipeline().documents([ db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ]).execute()
Kotlin
var results: Task<Pipeline.Snapshot> // Return all restaurants in San Francisco results = db.pipeline().collection("cities/sf/restaurants").execute() // Return all restaurants results = db.pipeline().collectionGroup("restaurants").execute() // Return all documents across all collections in the database (the entire database) results = db.pipeline().database().execute() // Batch read of 3 documents results = db.pipeline().documents( db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ).execute()
Java
Task<Pipeline.Snapshot> results; // Return all restaurants in San Francisco results = db.pipeline().collection("cities/sf/restaurants").execute(); // Return all restaurants results = db.pipeline().collectionGroup("restaurants").execute(); // Return all documents across all collections in the database (the entire database) results = db.pipeline().database().execute(); // Batch read of 3 documents results = db.pipeline().documents( db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ).execute();
Python
# Return all restaurants in San Francisco results = client.pipeline().collection("cities/sf/restaurants").execute() # Return all restaurants results = client.pipeline().collection_group("restaurants").execute() # Return all documents across all collections in the database (the entire database) results = client.pipeline().database().execute() # Batch read of 3 documents results = ( client.pipeline() .documents( client.collection("cities").document("SF"), client.collection("cities").document("DC"), client.collection("cities").document("NY"), ) .execute() )
Comme pour toutes les autres étapes, l'ordre des résultats de ces étapes d'entrée n'est pas stable. Un opérateur sort(...) doit toujours être ajouté si un ordre spécifique est souhaité.
Où
L'étape where(...) agit comme une opération de filtrage traditionnelle sur les documents générés à partir de l'étape précédente et reflète principalement la syntaxe "where" existante pour les requêtes existantes. Tout document pour lequel une expression donnée est évaluée à une valeur non true est filtré des documents renvoyés.
Plusieurs instructions where(...) peuvent être chaînées et agir comme une expression and(...). Par exemple, les deux requêtes suivantes sont logiquement équivalentes et peuvent être utilisées de manière interchangeable.
Web
let results; results = await execute(db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) ); results = await execute(db.pipeline().collection("books") .where(and(field("rating").equal(5), field("published").lessThan(1900))) );
Swift
var results: Pipeline.Snapshot results = try await db.pipeline().collection("books") .where(Field("rating").equal(5)) .where(Field("published").lessThan(1900)) .execute() results = try await db.pipeline().collection("books") .where(Field("rating").equal(5) && Field("published").lessThan(1900)) .execute()
Kotlin
var results: Task<Pipeline.Snapshot> results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute() results = db.pipeline().collection("books") .where(Expression.and(field("rating").equal(5), field("published").lessThan(1900))) .execute()
Java
Task<Pipeline.Snapshot> results; results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute(); results = db.pipeline().collection("books") .where(Expression.and( field("rating").equal(5), field("published").lessThan(1900) )) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import And, Field results = ( client.pipeline() .collection("books") .where(Field.of("rating").equal(5)) .where(Field.of("published").less_than(1900)) .execute() ) results = ( client.pipeline() .collection("books") .where(And(Field.of("rating").equal(5), Field.of("published").less_than(1900))) .execute() )
Sélectionner / Ajouter et supprimer des champs
select(...), add_fields(...) et remove_fields(...) vous permettent tous de modifier les champs renvoyés à partir d'une étape précédente. Ces trois éléments sont généralement appelés étapes de style de projection.
select(...) et add_fields(...) vous permettent de spécifier le résultat d'une expression dans un nom de champ fourni par l'utilisateur. Une expression qui génère une erreur génère une valeur null. select(...) ne renvoie que les documents avec les noms de champs spécifiés, tandis que add_fields(...) étend le schéma de l'étape précédente (en écrasant potentiellement les valeurs avec des noms de champs identiques).
remove_fields(...) permet de spécifier un ensemble de champs à supprimer de l'étape précédente. La spécification de noms de champs qui n'existent pas est une opération sans effet.
Consultez la section Limiter les champs à renvoyer ci-dessous, mais en général, l'utilisation d'une telle étape pour limiter le résultat aux seuls champs nécessaires dans le client est utile pour réduire le coût et la latence de la plupart des requêtes.
Cumul / Distinct
L'étape aggregate(...) vous permet d'effectuer une série d'agrégations sur les documents d'entrée. Par défaut, tous les documents sont agrégés, mais un argument grouping facultatif peut être fourni, ce qui permet d'agréger les documents d'entrée dans différents buckets.
Web
const results = await execute(db.pipeline() .collection("books") .aggregate( field("rating").average().as("avg_rating") ) .distinct(field("genre")) );
Swift
let results = try await db.pipeline() .collection("books") .aggregate([ Field("rating").average().as("avg_rating") ], groups: [ Field("genre") ]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .aggregate( AggregateStage .withAccumulators(AggregateFunction.average("rating").alias("avg_rating")) .withGroups(field("genre")) ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .aggregate(AggregateStage .withAccumulators( AggregateFunction.average("rating").alias("avg_rating")) .withGroups(field("genre"))) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .aggregate( Field.of("rating").average().as_("avg_rating"), groups=[Field.of("genre")] ) .execute() )
Lorsque groupings n'est pas spécifié, cette étape ne génère qu'un seul document. Sinon, un document est généré pour chaque combinaison unique de valeurs groupings.
L'étape distinct(...) est un opérateur d'agrégation simplifié qui permet de générer uniquement les groupings uniques sans aucun accumulateur. Il se comporte de manière identique à aggregate(...) à tous les autres égards. Vous trouverez un exemple ci-dessous :
Web
const results = await execute(db.pipeline() .collection("books") .distinct( field("author").toUpper().as("author"), field("genre") ) );
Swift
let results = try await db.pipeline() .collection("books") .distinct([ Field("author").toUpper().as("author"), Field("genre") ]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .distinct( field("author").toUpper().alias("author"), field("genre") ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .distinct( field("author").toUpper().alias("author"), field("genre") ) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .distinct(Field.of("author").to_upper().as_("author"), "genre") .execute() )
Fonctions
Les fonctions sont un élément de base pour créer des expressions et des requêtes complexes. Pour obtenir une liste complète des fonctions avec des exemples, consultez la documentation de référence sur les fonctions. Pour rappel, considérez la structure d'une requête typique :

De nombreuses étapes acceptent des expressions contenant une ou plusieurs fonctions. L'utilisation la plus courante des fonctions se trouve dans les étapes where(...) et select(...). Il existe deux principaux types de fonctions que vous devez connaître :
Web
let results; // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = await execute(db.pipeline().collection("books") .select(field("current").logicalMinimum(field("updated")).as("price_min")) ); // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = await execute(db.pipeline().collection("books") .aggregate(field("price").minimum().as("min_price")) );
Swift
var results: Pipeline.Snapshot // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = try await db.pipeline().collection("books") .select([ Field("current").logicalMinimum(["updated"]).as("price_min") ]) .execute() // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = try await db.pipeline().collection("books") .aggregate([Field("price").minimum().as("min_price")]) .execute()
Kotlin
var results: Task<Pipeline.Snapshot> // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = db.pipeline().collection("books") .select( field("current").logicalMinimum("updated").alias("price_min") ) .execute() // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = db.pipeline().collection("books") .aggregate(AggregateFunction.minimum("price").alias("min_price")) .execute()
Java
Task<Pipeline.Snapshot> results; // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = db.pipeline().collection("books") .select( field("current").logicalMinimum("updated").alias("price_min") ) .execute(); // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = db.pipeline().collection("books") .aggregate(AggregateFunction.minimum("price").alias("min_price")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field # Type 1: Scalar (for use in non-aggregation stages) # Example: Return the min store price for each book. results = ( client.pipeline() .collection("books") .select( Field.of("current").logical_minimum(Field.of("updated")).as_("price_min") ) .execute() ) # Type 2: Aggregation (for use in aggregate stages) # Example: Return the min price of all books. results = ( client.pipeline() .collection("books") .aggregate(Field.of("price").minimum().as_("min_price")) .execute() )
Limites
Dans la plupart des cas, l'édition Enterprise n'impose pas de limites sur la forme de la requête. En d'autres termes, vous n'êtes pas limité à un petit nombre de valeurs dans une requête IN ou OR. Au lieu de cela, vous devez connaître deux limites principales :
- Délai : 60 secondes (identique à l'édition Standard).
- Utilisation de la mémoire : limite de 128 Mio sur la quantité de données matérialisées lors de l'exécution de la requête.
Erreurs
Vous pouvez rencontrer des requêtes ayant échoué pour plusieurs raisons. Voici un lien vers les erreurs courantes et l'action associée que vous pouvez effectuer :
| Code d'erreur | Action |
DEADLINE_EXCEEDED
|
La requête que vous exécutez dépasse le délai de 60 secondes et nécessite une optimisation supplémentaire. Consultez la section sur les performances pour obtenir des conseils. Si vous ne parvenez pas à identifier la cause du problème, contactez l'équipe. |
RESOURCE_EXHAUSTED
|
La requête que vous exécutez dépasse les limites de mémoire et nécessite une optimisation supplémentaire. Consultez la section sur les performances pour obtenir des conseils. Si vous ne parvenez pas à identifier la cause du problème, contactez l'équipe. |
INTERNAL
|
Contactez l'équipe pour obtenir de l'aide. |
Performances
Contrairement aux requêtes existantes, les opérations de pipeline ne nécessitent pas toujours la présence d'un index. Cela signifie qu'une requête peut présenter une latence plus élevée que les requêtes existantes, qui auraient échoué immédiatement avec une erreur d'index manquant FAILED_PRECONDITION. Pour améliorer les performances des opérations de pipeline, vous pouvez suivre quelques étapes.
Créer des index
Index utilisé
L'explication de la requête vous permet de déterminer si votre requête est diffusée par un index ou si elle revient à une opération moins efficace, comme une analyse de table. Si votre requête n'est pas entièrement diffusée à partir d'un index, vous pouvez créer un index en suivant les instructions.
Créer des index
Vous pouvez suivre la documentation existante sur la gestion des index pour créer des index. Avant de créer un index, familiarisez-vous avec les bonnes pratiques générales concernant les index dans Cloud Firestore. Pour vous assurer que votre requête peut exploiter les index, suivez les bonnes pratiques pour créer des index avec des champs dans l'ordre suivant :
- Tous les champs qui seront utilisés dans les filtres d'égalité (dans n'importe quel ordre)
- Tous les champs qui seront triés (dans le même ordre)
- Champs qui seront utilisés dans les filtres de plage ou d'inégalité par ordre décroissant de sélectivité des contraintes de requête
Par exemple, pour la requête suivante,
Web
const results = await execute(db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) );
Swift
let results = try await db.pipeline() .collection("books") .where(Field("published").lessThan(1900)) .where(Field("genre").equal("Science Fiction")) .where(Field("rating").greaterThan(4.3)) .sort([Field("published").descending()]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .where(Field.of("published").less_than(1900)) .where(Field.of("genre").equal("Science Fiction")) .where(Field.of("rating").greater_than(4.3)) .sort(Field.of("published").descending()) .execute() )
L'index recommandé est un index de portée de collection sur books pour (genre [...], published DESC, avg_rating DESC).
Densité d'index
Cloud Firestore est compatible avec les index denses et non denses. Pour en savoir plus, consultez la section Densité d'index.
Requêtes couvertes + index secondaires
Cloud Firestore peut ignorer la récupération du document complet et ne renvoyer que les résultats de l'index si tous les champs renvoyés sont présents dans un index secondaire. Cela entraîne normalement une amélioration significative de la latence (et des coûts). Utilisez l'exemple de requête ci-dessous :
Web
const results = await execute(db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) );
Swift
let results = try await db.pipeline() .collection("books") .where(Field("category").like("%fantasy%")) .where(Field("title").exists()) .where(Field("author").exists()) .select([Field("title"), Field("author")]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .where(Field.of("category").like("%fantasy%")) .where(Field.of("title").exists()) .where(Field.of("author").exists()) .select("title", "author") .execute() )
Si la base de données possède déjà un index de portée de collection sur books pour (category [...], title [...], author [...]), elle peut éviter de récupérer quoi que ce soit à partir des documents principaux eux-mêmes. Dans ce cas, l'ordre dans l'index n'a pas d'importance. [...] est utilisé pour le signifier.
Limiter les champs à renvoyer
Par défaut, une requête Cloud Firestore renvoie tous les champs d'un document, de la même manière qu'un SELECT * dans les systèmes traditionnels. Toutefois, si votre application n'a besoin que d'un sous-ensemble des champs, les étapes select(...) ou restrict(...) peuvent être utilisées pour envoyer ce filtrage côté serveur. Cela réduira à la fois la taille de la réponse (diminuant ainsi le coût de sortie réseau) et la latence.
Outils de dépannage
Explication de la requête
L'explication de la requête vous permet de visualiser les métriques d'exécution et les détails sur les index utilisés.
Métriques
Les opérations de pipeline sont entièrement intégrées aux métriques Cloud Firestore existantes.
Problèmes connus / Limites
Index spécialisés
Les opérations de pipeline ne sont pas encore compatibles avec les types d'index array-contains et vector existants. Au lieu de simplement rejeter ces requêtes, Cloud Firestore tente d'utiliser d'autres index ascending et descending existants. Il est prévu que, pendant la version preview privée, les opérations de pipeline avec de telles expressions array_contains ou find_nearest soient plus lentes que leurs équivalents existants.
Pagination
La compatibilité avec la pagination facile sur un ensemble de résultats n'est pas disponible pendant la version preview privée. Vous pouvez contourner ce problème en chaînant des étapes where(...) et sort(...) équivalentes, comme indiqué ci-dessous.
Web
// Existing pagination via `startAt()` const q = query(collection(db, "cities"), orderBy("population"), startAt(1000000)); // Private preview workaround using pipelines const pageSize = 2; const pipeline = db.pipeline() .collection("cities") .select("name", "population", "__name__") .sort(field("population").descending(), field("__name__").ascending()); // Page 1 results let snapshot = await execute(pipeline.limit(pageSize)); // End of page marker const lastDoc = snapshot.results[snapshot.results.length - 1]; // Page 2 results snapshot = await execute( pipeline .where( or( and( field("population").equal(lastDoc.get("population")), field("__name__").greaterThan(lastDoc.ref) ), field("population").lessThan(lastDoc.get("population")) ) ) .limit(pageSize) );
Swift
// Existing pagination via `start(at:)` let query = db.collection("cities").order(by: "population").start(at: [1000000]) // Private preview workaround using pipelines let pipeline = db.pipeline() .collection("cities") .where(Field("population").greaterThanOrEqual(1000000)) .sort([Field("population").descending()])
Kotlin
// Existing pagination via `startAt()` val query = db.collection("cities").orderBy("population").startAt(1000000) // Private preview workaround using pipelines val pipeline = db.pipeline() .collection("cities") .where(field("population").greaterThanOrEqual(1000000)) .sort(field("population").descending())
Java
// Existing pagination via `startAt()` Query query = db.collection("cities").orderBy("population").startAt(1000000); // Private preview workaround using pipelines Pipeline pipeline = db.pipeline() .collection("cities") .where(field("population").greaterThanOrEqual(1000000)) .sort(field("population").descending());
Python
from google.cloud.firestore_v1.pipeline_expressions import Field # Existing pagination via `start_at()` query = ( client.collection("cities") .order_by("population") .start_at({"population": 1_000_000}) ) # Private preview workaround using pipelines pipeline = ( client.pipeline() .collection("cities") .where(Field.of("population").greater_than_or_equal(1_000_000)) .sort(Field.of("population").descending()) )
Compatibilité avec l'émulateur
L'émulateur n'est pas compatible avec les opérations de pipeline.
Compatibilité en temps réel et hors connexion
Les opérations de pipeline ne disposent pas encore de fonctionnalités en temps réel et hors connexion.
Étape suivante
- Commencez à explorer la documentation de référence sur les fonctions et les étapes.