Class Pipeline (3.41.0)

public final class Pipeline

The Pipeline class provides a flexible and expressive framework for building complex data transformation and query pipelines for Firestore.

A pipeline takes data sources, such as Firestore collections or collection groups, and applies a series of stages that are chained together. Each stage takes the output from the previous stage (or the data source) and produces an output for the next stage (or as the final output of the pipeline).

Expressions from com.google.cloud.firestore.pipeline.expressions can be used within each stages to filter and transform data through the stage.

NOTE: The chained stages do not prescribe exactly how Firestore will execute the pipeline. Instead, Firestore only guarantees that the result is the same as if the chained stages were executed in order.

Usage Examples:


 Firestore firestore; // A valid firestore instance.

 // Example 1: Select specific fields and rename 'rating' to 'bookRating'
 Snapshot results1 = firestore.pipeline()
     .collection("books")
     .select(field("title"), field("author"), field("rating").as("bookRating"))
     .execute()
     .get();

 // Example 2: Filter documents where 'genre' is "Science Fiction" and
 // 'published' is after 1950
 Snapshot results2 = firestore.pipeline()
     .collection("books")
     .where(and(equal("genre", "Science Fiction"), greaterThan("published", 1950)))
     .execute()
     .get();
 // Same as above but using methods on expressions as opposed to static
 // functions.
 results2 = firestore.pipeline()
     .collection("books")
     .where(and(field("genre").equal("Science Fiction"), field("published").greaterThan(1950)))
     .execute()
     .get();

 // Example 3: Calculate the average rating of books published after 1980
 Snapshot results3 = firestore.pipeline()
     .collection("books")
     .where(greaterThan("published", 1980))
     .aggregate(average("rating").as("averageRating"))
     .execute()
     .get();
 

Inheritance

java.lang.Object > Pipeline

Methods

addFields(Selectable field, Selectable[] additionalFields)

public Pipeline addFields(Selectable field, Selectable[] additionalFields)

Adds new fields to outputs from previous stages.

This stage allows you to compute values on-the-fly based on existing data from previous stages or constants. You can use this to create new fields or overwrite existing ones (if there is name overlaps).

The added fields are defined using Selectable expressions, which can be:

Example:


 firestore.pipeline().collection("books")
     .addFields(
         field("rating").as("bookRating"), // Rename 'rating' to 'bookRating'
         add(5, field("quantity")).as("totalCost") // Calculate 'totalCost'
     );
 
Parameters
Name Description
field Selectable

The field to add to the documents, specified as Selectable expressions.

additionalFields Selectable[]

The additional fields to add to the documents, specified as Selectable expressions.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

aggregate(AliasedAggregate[] accumulators)

public Pipeline aggregate(AliasedAggregate[] accumulators)

Performs aggregation operations on the documents from previous stages.

This stage allows you to calculate aggregate values over a set of documents. You define the aggregations to perform using AliasedExpression expressions which are typically results of calling Expression#as(String) on AggregateFunction instances.

Example:


 // Calculate the average rating and the total number of books
 firestore.pipeline().collection("books")
     .aggregate(
         field("rating").average().as("averageRating"),
         countAll().as("totalBooks"));
 
Parameter
Name Description
accumulators AliasedAggregate[]

The AliasedExpression expressions, each wrapping an AggregateFunction and provide a name for the accumulated results.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

aggregate(Aggregate aggregate)

public Pipeline aggregate(Aggregate aggregate)

Performs optionally grouped aggregation operations on the documents from previous stages.

This stage allows you to calculate aggregate values over a set of documents, optionally grouped by one or more fields or functions. You can specify:

  • Grouping Fields or Functions: One or more fields or functions to group the documents by. For each distinct combination of values in these fields, a separate group is created. If no grouping fields are provided, a single group containing all documents is used. Not specifying groups is the same as putting the entire inputs into one group.
  • Accumulators: One or more accumulation operations to perform within each group. These are defined using AliasedExpression expressions, which are typically created by calling Expression#as(String) on AggregateFunction instances. Each aggregation calculates a value (e.g., sum, average, count) based on the documents within its group.

Example:


 // Calculate the average rating for each genre.
 firestore.pipeline().collection("books")
     .aggregate(
         Aggregate
             .withAccumulators(average("rating").as("avg_rating"))
             .withGroups("genre"));
 
Parameter
Name Description
aggregate Aggregate

An Aggregate object that specifies the grouping fields (if any) and the aggregation operations to perform.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

aggregate(Aggregate aggregate, AggregateOptions options)

public Pipeline aggregate(Aggregate aggregate, AggregateOptions options)
Parameters
Name Description
aggregate Aggregate
options AggregateOptions
Returns
Type Description
Pipeline

define(AliasedExpression expression, AliasedExpression[] additionalExpressions)

public Pipeline define(AliasedExpression expression, AliasedExpression[] additionalExpressions)

Defines one or more variables in the pipeline's scope. define is used to bind a value to a variable for internal reuse within the pipeline body (accessed via the Expression#variable(String) function).

This stage is useful for declaring reusable values or intermediate calculations that can be referenced multiple times in later parts of the pipeline, improving readability and maintainability.

Each variable is defined using an AliasedExpression, which pairs an expression with a name (alias).

Example:


 firestore.pipeline().collection("products")
     .define(
         multiply(field("price"), 0.9).as("discountedPrice"),
         add(field("stock"), 10).as("newStock"))
     .where(lessThan(variable("discountedPrice"), 100))
     .select(field("name"), variable("newStock"));
 
Parameters
Name Description
expression AliasedExpression

The expression to define using AliasedExpression.

additionalExpressions AliasedExpression[]

Additional expressions to define using AliasedExpression.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

delete()

public Pipeline delete()

Performs a delete operation on documents from previous stages.

Example:


 // Delete all documents in the "logs" collection where "status" is "archived"
 firestore.pipeline()
     .collection("logs")
     .where(field("status").equal("archived"))
     .delete()
     .execute()
     .get();
 
Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

distinct(Selectable[] selectables)

public Pipeline distinct(Selectable[] selectables)

Returns a set of distinct Expression values from the inputs to this stage.

This stage run through the results from previous stages to include only results with unique combinations of Expression values (Field, FunctionExpression, etc).

The parameters to this stage are defined using Selectable expressions, which can be:

Example:


 // Get a list of unique author names in uppercase and genre combinations.
 firestore.pipeline().collection("books")
     .distinct(toUppercase(field("author")).as("authorName"), field("genre"))
     .select("authorName");
 
Parameter
Name Description
selectables Selectable[]

The Selectable expressions to consider when determining distinct value combinations.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

distinct(String[] fields)

public Pipeline distinct(String[] fields)

Returns a set of distinct field values from the inputs to this stage.

This stage run through the results from previous stages to include only results with unique combinations of values for the specified fields and produce these fields as the output.

Example:


 // Get a list of unique genres.
 firestore.pipeline().collection("books")
     .distinct("genre");
 
Parameter
Name Description
fields String[]

The fields to consider when determining distinct values.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

execute()

public ApiFuture<Pipeline.Snapshot> execute()

Executes this pipeline and returns a future to represent the asynchronous operation.

The returned ApiFuture can be used to track the progress of the pipeline execution and retrieve the results (or handle any errors) asynchronously.

The pipeline results are returned as a list of PipelineResult objects. Each PipelineResult typically represents a single key/value map that has passed through all the stages of the pipeline, however this might differ depends on the stages involved in the pipeline. For example:

  • If there are no stages or only transformation stages, each PipelineResult represents a single document.
  • If there is an aggregation, only a single PipelineResult is returned, representing the aggregated results over the entire dataset .
  • If there is an aggregation stage with grouping, each PipelineResult represents a distinct group and its associated aggregated values.

Example:


 ApiFuture<Snapshot> futureResults = firestore.pipeline().collection("books")
     .where(gt("rating", 4.5))
     .select("title", "author", "rating")
     .execute();
 
Returns
Type Description
ApiFuture<Snapshot>

An ApiFuture representing the asynchronous pipeline execution.

execute(ApiStreamObserver<PipelineResult> observer)

public void execute(ApiStreamObserver<PipelineResult> observer)

Executes this pipeline, providing results to the given ApiStreamObserver as they become available.

This method allows you to process pipeline results in a streaming fashion, rather than waiting for the entire pipeline execution to complete. The provided ApiStreamObserver will receive:

  • onNext(PipelineResult): Called for each PipelineResult produced by the pipeline. Each PipelineResult typically represents a single key/value map that has passed through all the stages. However, the exact structure might differ based on the stages involved in the pipeline (as described in #execute()).
  • onError(Throwable): Called if an error occurs during pipeline execution.
  • onCompleted(): Called when the pipeline has finished processing all documents.

Example:


 firestore.pipeline().collection("books")
     .where(gt("rating", 4.5))
     .select("title", "author", "rating")
     .execute(new ApiStreamObserver<PipelineResult>() {
         @Override
         public void onNext(PipelineResult result) {
             // Process each result as it arrives
             System.out.println(result.getData());
         }

         @Override
         public void onError(Throwable t) {
             // Handle errors during execution
             t.printStackTrace();
         }

         @Override
         public void onCompleted() {
             System.out.println("Pipeline execution completed.");
         }
     });
 
Parameter
Name Description
observer ApiStreamObserver<PipelineResult>

The ApiStreamObserver to receive pipeline results and events.

execute(PipelineExecuteOptions options)

public ApiFuture<Pipeline.Snapshot> execute(PipelineExecuteOptions options)
Parameter
Name Description
options PipelineExecuteOptions
Returns
Type Description
ApiFuture<Snapshot>

findNearest(Expression property, double[] vector, FindNearest.DistanceMeasure distanceMeasure, FindNearestOptions options)

public Pipeline findNearest(Expression property, double[] vector, FindNearest.DistanceMeasure distanceMeasure, FindNearestOptions options)

Performs vector distance (similarity) search with given parameters to the stage inputs.

This stage adds a "nearest neighbor search" capability to your pipelines. Given an expression that evaluates to a vector and a target vector, this stage will identify and return the inputs whose vector expression is closest to the target vector, using the parameters specified in options.

Example:


 // Find books with similar "topicVectors" to the given targetVector
 firestore.pipeline().collection("books")
     .findNearest(
        field("topicVectors"),
        targetVector,
        FindNearest.DistanceMeasure.COSINE,
        new FindNearestOptions()
          .withLimit(10)
          .withDistanceField("distance"));
 
Parameters
Name Description
property Expression

The expression that evaluates to a vector value using the stage inputs.

vector double[]

The target vector to compare against.

distanceMeasure FindNearest.DistanceMeasure

The distance measure to use: cosine, euclidean, etc.

options FindNearestOptions

Configuration options for the nearest neighbor search, such as limit and output distance field name.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

findNearest(String fieldName, double[] vector, FindNearest.DistanceMeasure distanceMeasure, FindNearestOptions options)

public Pipeline findNearest(String fieldName, double[] vector, FindNearest.DistanceMeasure distanceMeasure, FindNearestOptions options)

Performs vector distance (similarity) search with given parameters to the stage inputs.

This stage adds a "nearest neighbor search" capability to your pipelines. Given a field that stores vectors and a target vector, this stage will identify and return the inputs whose vector field is closest to the target vector, using the parameters specified in options.

Example:


 // Find books with similar "topicVectors" to the given targetVector
 firestore.pipeline().collection("books")
     .findNearest("topicVectors", targetVector, FindNearest.DistanceMeasure.COSINE,
        new FindNearestOptions()
          .withLimit(10)
          .withDistanceField("distance"));
 
Parameters
Name Description
fieldName String

The name of the field containing the vector data. This field should store VectorValue.

vector double[]

The target vector to compare against.

distanceMeasure FindNearest.DistanceMeasure

The distance measure to use: cosine, euclidean, etc.

options FindNearestOptions

Configuration options for the nearest neighbor search, such as limit and output distance field name.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

limit(int limit)

public Pipeline limit(int limit)

Limits the maximum number of documents returned by previous stages to limit.

This stage is particularly useful when you want to retrieve a controlled subset of data from a potentially large result set. It's often used for:

  • Pagination: In combination with #offset(int) to retrieve specific pages of results.
  • Limiting Data Retrieval: To prevent excessive data transfer and improve performance, especially when dealing with large collections.

Example:


 // Limit the results to the top 10 highest-rated books
 firestore.pipeline().collection("books")
     .sort(field("rating").descending())
     .limit(10);
 
Parameter
Name Description
limit int

The maximum number of documents to return.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

offset(int offset)

public Pipeline offset(int offset)

Skips the first offset number of documents from the results of previous stages.

This stage is useful for implementing pagination in your pipelines, allowing you to retrieve results in chunks. It is typically used in conjunction with #limit(int) to control the size of each page.

Example:


 // Retrieve the second page of 20 results
 firestore.pipeline().collection("books")
     .sort(field("published").descending())
     .offset(20)  // Skip the first 20 results
     .limit(20);   // Take the next 20 results
 
Parameter
Name Description
offset int

The number of documents to skip.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

rawStage(RawStage stage)

public Pipeline rawStage(RawStage stage)

Performs an insert operation using documents from previous stages. Adds a generic stage to the pipeline.

This method provides a flexible way to extend the pipeline's functionality by adding custom stages. Each generic stage is defined by a unique name and a set of params that control its behavior.

Example (Assuming there is no "where" stage available in SDK):


 // Assume we don't have a built-in "where" stage
 Map<String, Object> whereParams = new HashMap<>();
 whereParams.put("condition", field("published").lt(1900));

 firestore.pipeline().collection("books")
     .genericStage("where", Lists.newArrayList(field("published").lt(1900)), new RawOptions()) // Custom "where" stage
     .select("title", "author");
 
Parameter
Name Description
stage RawStage
Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

removeFields(Field field, Field[] additionalFields)

public Pipeline removeFields(Field field, Field[] additionalFields)

Remove fields from outputs of previous stages.

Example:


 firestore.pipeline().collection("books")
     .removeFields(
         field("rating"), field("cost"));
 
Parameters
Name Description
field Field

The field to remove.

additionalFields Field[]

The additional fields to remove.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

removeFields(String field, String[] additionalFields)

public Pipeline removeFields(String field, String[] additionalFields)

Remove fields from outputs of previous stages.

Example:


 firestore.pipeline().collection("books")
     .removeFields(
         "rating", "cost");
 
Parameters
Name Description
field String

The fields to remove.

additionalFields String[]

The additional fields to remove.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

replaceWith(Expression expr)

public Pipeline replaceWith(Expression expr)

Fully overwrites all fields in a document with those coming from a nested map.

This stage allows you to emit a map value as a document. Each key of the map becomes a field on the document that contains the corresponding value.

Example:


 // Input.
 // {
 //  "name": "John Doe Jr.",
 //  "parents": {
 //    "father": "John Doe Sr.",
 //    "mother": "Jane Doe"
 //  }
 // }

 // Emit parents as document.
 firestore.pipeline().collection("people").replaceWith(field("parents"));

 // Output
 // {
 //  "father": "John Doe Sr.",
 //  "mother": "Jane Doe"
 // }
 
Parameter
Name Description
expr Expression

The Expression field containing the nested map.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

replaceWith(String fieldName)

public Pipeline replaceWith(String fieldName)

Fully overwrites all fields in a document with those coming from a nested map.

This stage allows you to emit a map value as a document. Each key of the map becomes a field on the document that contains the corresponding value.

Example:


 // Input.
 // {
 //  "name": "John Doe Jr.",
 //  "parents": {
 //    "father": "John Doe Sr.",
 //    "mother": "Jane Doe"
 //   }
 // }

 // Emit parents as document.
 firestore.pipeline().collection("people").replaceWith("parents");

 // Output
 // {
 //  "father": "John Doe Sr.",
 //  "mother": "Jane Doe"
 // }
 
Parameter
Name Description
fieldName String

The name of the field containing the nested map.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

sample(Sample sample)

public Pipeline sample(Sample sample)

Performs a pseudo-random sampling of the documents from the previous stage.

This stage will filter documents pseudo-randomly. The 'options' parameter specifies how sampling will be performed. See SampleOptions for more information.

Examples:


 // Sample 10 books, if available.
 firestore.pipeline().collection("books")
     .sample(Sample.withDocLimit(10));

 // Sample 50% of books.
 firestore.pipeline().collection("books")
     .sample(Sample.withPercentage(0.5));
 
Parameter
Name Description
sample Sample

The Sample specifies how sampling is performed.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

sample(int limit)

public Pipeline sample(int limit)

Performs a pseudo-random sampling of the documents from the previous stage.

This stage will filter documents pseudo-randomly. The 'limit' parameter specifies the number of documents to emit from this stage, but if there are fewer documents from previous stage than the 'limit' parameter, then no filtering will occur and all documents will pass through.

Example:


 // Sample 10 books, if available.
 firestore.pipeline().collection("books")
     .sample(10);
 
Parameter
Name Description
limit int

The number of documents to emit, if possible.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

search(Search searchStage)

public Pipeline search(Search searchStage)

Adds a search stage to the Pipeline.

This must be the first stage of the pipeline.

A limited set of expressions are supported in the search stage.

Parameter
Name Description
searchStage Search

An object that specifies how search is performed.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

select(Selectable selection, Selectable[] additionalSelections)

public Pipeline select(Selectable selection, Selectable[] additionalSelections)

Selects or creates a set of fields from the outputs of previous stages.

The selected fields are defined using Selectable expressions, which can be:

If no selections are provided, the output of this stage is empty. Use com.google.cloud.firestore.Pipeline#addFields(Selectable, Selectable...) instead if only additions are desired.

Example:


 firestore.pipeline().collection("books")
   .select(
     field("name"),
     field("address").toUppercase().as("upperAddress"),
   );
 
Parameters
Name Description
selection Selectable

The field to include in the output documents, specified as Selectable expressions.

additionalSelections Selectable[]

The additional fields to include in the output documents,

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

select(String field, String[] additionalFields)

public Pipeline select(String field, String[] additionalFields)

Selects a set of fields from the outputs of previous stages.

If no selections are provided, the output of this stage is empty. Use com.google.cloud.firestore.Pipeline#addFields(Selectable, Selectable...) instead if only additions are desired.

Example:


 firestore.collection("books")
     .select("name", "address");

 // The above is a shorthand of this:
 firestore.pipeline().collection("books")
     .select(field("name"), field("address"));
 
Parameters
Name Description
field String

The name of the field to include in the output documents.

additionalFields String[]

The additional fields to include in the output documents.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

sort(Ordering[] orders)

public Pipeline sort(Ordering[] orders)

Sorts the documents from previous stages based on one or more Ordering criteria.

This stage allows you to order the results of your pipeline. You can specify multiple Ordering instances to sort by multiple fields in ascending or descending order. If documents have the same value for a field used for sorting, the next specified ordering will be used. If all orderings result in equal comparison, the documents are considered equal and the order is unspecified.

Example:


 // Sort books by rating in descending order, and then by title in ascending order for books with the same rating
 firestore.pipeline().collection("books")
     .sort(
         Ordering.of("rating").descending(),
         Ordering.of("title")  // Ascending order is the default
     );
 
Parameter
Name Description
orders Ordering[]

One or more Ordering instances specifying the sorting criteria.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

toArrayExpression()

public Expression toArrayExpression()

Converts the pipeline into an array expression.

Result Unwrapping: For simpler access, subqueries producing a single field automatically unwrap that value to the top level, ignoring the inner alias. If the subquery returns multiple fields, they are preserved as a map.

Example 1: Single field unwrapping


 // Get a list of all reviewer names for each book
 db.pipeline().collection("books")
     .define(field("id").as("book_id"))
     .addFields(
         db.pipeline().collection("reviews")
             .where(field("book_id").equal(variable("book_id")))
             .select(field("reviewer").as("name"))
             .toArrayExpression()
             .as("reviewers"))
 

The result set is unwrapped from "reviewers": [{ "name": "Alice" }, { "name": "Bob" }] to "reviewers": ["Alice", "Bob"].


 // Output Document:
 [
   {
     "id": "1",
     "title": "1984",
     "reviewers": ["Alice", "Bob"]
   }
 ]
 

Example 2: Multiple fields (Map)


 // Get a list of reviews (reviewer and rating) for each book
 db.pipeline().collection("books")
     .define(field("id").as("book_id"))
     .addFields(
         db.pipeline().collection("reviews")
             .where(field("book_id").equal(variable("book_id")))
             .select(field("reviewer"), field("rating"))
             .toArrayExpression()
             .as("reviews"))
 

When the subquery produces multiple fields, they are kept as objects in the array:


 // Output Document:
 [
   {
     "id": "1",
     "title": "1984",
     "reviews": [
       { "reviewer": "Alice", "rating": 5 },
       { "reviewer": "Bob", "rating": 4 }
     ]
   }
 ]
 
Returns
Type Description
Expression

A new Expression representing the pipeline as an array.

toProto()

public Pipeline toProto()
Returns
Type Description
Pipeline

toProtoValue()

public Value toProtoValue()
Returns
Type Description
Value

toScalarExpression()

public Expression toScalarExpression()

Converts this Pipeline into an expression that evaluates to a single scalar result. Used for 1:1 lookups or Aggregations when the subquery is expected to return a single value or object.

Runtime Validation: The runtime will validate that the result set contains exactly one item. It throws a runtime error if the result has more than one item, and evaluates to null if the pipeline has zero results.

Result Unwrapping: For simpler access, subqueries producing a single field automatically unwrap that value to the top level, ignoring the inner alias. If the subquery returns multiple fields, they are preserved as a map.

Example 1: Single field unwrapping


 // Calculate average rating for each restaurant using a subquery
 db.pipeline().collection("restaurants")
     .define(field("id").as("rid"))
     .addFields(
         db.pipeline().collection("reviews")
             .where(field("restaurant_id").equal(variable("rid")))
             // Inner aggregation returns a single document
             .aggregate(AggregateFunction.average("rating").as("value"))
             // Convert Pipeline -> Scalar Expression (validates result is 1 item)
             .toScalarExpression()
             .as("average_rating"))
 

The result set is unwrapped twice: from "average_rating": [{ "value": 4.5 }] to "average_rating": { "value": 4.5 }, and finally to "average_rating": 4.5.


 // Output Document:
 [
   {
     "id": "123",
     "name": "The Burger Joint",
     "cuisine": "American",
     "average_rating": 4.5
   },
   {
     "id": "456",
     "name": "Sushi World",
     "cuisine": "Japanese",
     "average_rating": 4.8
   }
 ]
 

Example 2: Multiple fields (Map)


 // For each restaurant, calculate review statistics (average rating AND total
 // count)
 db.pipeline().collection("restaurants")
     .define(field("id").as("rid"))
     .addFields(
         db.pipeline().collection("reviews")
             .where(field("restaurant_id").equal(variable("rid")))
             .aggregate(
                 AggregateFunction.average("rating").as("avg_score"),
                 AggregateFunction.countAll().as("review_count"))
             .toScalarExpression()
             .as("stats"))
 

When the subquery produces multiple fields, they are wrapped in a map:


 // Output Document:
 [
   {
     "id": "123",
     "name": "The Burger Joint",
     "cuisine": "American",
     "stats": {
       "avg_score": 4.0,
       "review_count": 3
     }
   },
   {
     "id": "456",
     "name": "Sushi World",
     "cuisine": "Japanese",
     "stats": {
       "avg_score": 4.8,
       "review_count": 120
     }
   }
 ]
 
Returns
Type Description
Expression

A new Expression representing the pipeline as a scalar.

union(Pipeline other)

public Pipeline union(Pipeline other)

Performs union of all documents from two pipelines, including duplicates.

This stage will pass through documents from previous stage, and also pass through documents from previous stage of the other Pipeline given in parameter. The order of documents emitted from this stage is undefined.

Example:


 // Emit documents from books collection and magazines collection.
 firestore.pipeline().collection("books")
     .union(firestore.pipeline().collection("magazines"));
 
Parameter
Name Description
other Pipeline

The other Pipeline that is part of union.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

unnest(Selectable expr)

public Pipeline unnest(Selectable expr)

Produces a document for each element in array found in previous stage document.

For each previous stage document, this stage will emit zero or more augmented documents. The input array found in the previous stage document field specified by the fieldName parameter, will for each input array element produce an augmented document. The input array element will augment the previous stage document by replacing the field specified by fieldName parameter with the element value.

In other words, the field containing the input array will be removed from the augmented document and replaced by the corresponding array element.

Example:


 // Input:
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tags": [ "comedy", "space", "adventure" ], ... }

 // Emit a book document for each tag of the book.
 firestore.pipeline().collection("books")
     .unnest(field("tags").as("tag"));

 // Output:
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 0, "tag": "comedy", ... }
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 1, "tag": "space", ... }
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 2, "tag": "adventure", ... }
 
Parameter
Name Description
expr Selectable

The name of the expression containing the array.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

unnest(Selectable field, UnnestOptions options)

public Pipeline unnest(Selectable field, UnnestOptions options)

Produces a document for each element in array found in previous stage document.

For each previous stage document, this stage will emit zero or more augmented documents. The input array found in the specified by Selectable expression parameter, will for each input array element produce an augmented document. The input array element will augment the previous stage document by assigning the Selectable alias the element value.

Example:


 // Input:
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tags": [ "comedy", "space",
 "adventure" ], ... }

 // Emit a book document for each tag of the book.
 firestore.pipeline().collection("books")
     .unnest(field("tags").as("tag"), UnnestOptions.indexField("tagIndex"));

 // Output:
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 0, "tag": "comedy",
 "tags": [ "comedy", "space", "adventure" ], ... }
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 1, "tag": "space", "tags":
 [ "comedy", "space", "adventure" ], ... }
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 2, "tag": "adventure",
 "tags": [ "comedy", "space", "adventure" ], ... }
 
Parameters
Name Description
field Selectable

The expression that evaluates to the input array.

options UnnestOptions

The UnnestOptions options.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

unnest(String fieldName, String alias)

public Pipeline unnest(String fieldName, String alias)

Produces a document for each element in array found in previous stage document.

For each previous stage document, this stage will emit zero or more augmented documents. The input array found in the previous stage document field specified by the fieldName parameter, will for each input array element produce an augmented document. The input array element will augment the previous stage document by replacing the field specified by fieldName parameter with the element value.

In other words, the field containing the input array will be removed from the augmented document and replaced by the corresponding array element.

Example:


 // Input:
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tags": [ "comedy", "space", "adventure" ], ... }

 // Emit a book document for each tag of the book.
 firestore.pipeline().collection("books")
     .unnest("tags", "tag");

 // Output:
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tag": "comedy", ... }
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tag": "space", ... }
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tag": "adventure", ... }
 
Parameters
Name Description
fieldName String

The name of the field containing the array.

alias String
Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

unnest(String fieldName, String alias, UnnestOptions options)

public Pipeline unnest(String fieldName, String alias, UnnestOptions options)

Produces a document for each element in array found in previous stage document.

For each previous stage document, this stage will emit zero or more augmented documents. The input array found in the previous stage document field specified by the fieldName parameter, will for each input array element produce an augmented document. The input array element will augment the previous stage document by replacing the field specified by fieldName parameter with the element value.

In other words, the field containing the input array will be removed from the augmented document and replaced by the corresponding array element.

Example:


 // Input:
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tags": [ "comedy", "space", "adventure" ], ... }

 // Emit a book document for each tag of the book.
 firestore.pipeline().collection("books")
     .unnest("tags", "tag", new UnnestOptions().withIndexField("tagIndex"));

 // Output:
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 0, "tag": "comedy", ... }
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 1, "tag": "space", ... }
 // { "title": "The Hitchhiker's Guide to the Galaxy", "tagIndex": 2, "tag": "adventure", ... }
 
Parameters
Name Description
fieldName String

The name of the field containing the array.

alias String
options UnnestOptions

The UnnestOptions options.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

update()

public Pipeline update()

Performs an update operation using documents from previous stages.

This method updates the documents in place based on the data flowing through the pipeline. To specify transformations, use #update(Selectable...).

Example 1: Update a collection's schema by adding a new field and removing an old one.


 firestore.pipeline()
     .collection("books")
     .addFields(constant("Fiction").as("genre"))
     .removeFields("old_genre")
     .update()
     .execute()
     .get();
 

Example 2: Update documents in place with data from literals.


 Map<String, Object> updateData = new HashMap<>();
 updateData.put("__name__", firestore.collection("books").document("book1"));
 updateData.put("status", "Updated");

 firestore.pipeline()
     .literals(updateData)
     .update()
     .execute()
     .get();
 
Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

update(Selectable[] transformedFields)

public Pipeline update(Selectable[] transformedFields)

Performs an update operation using documents from previous stages with specified transformations.

Example:


 // Update the "status" field to "Discounted" for all books where price > 50
 firestore.pipeline()
     .collection("books")
     .where(field("price").greaterThan(50))
     .update(constant("Discounted").as("status"))
     .execute()
     .get();
 
Parameter
Name Description
transformedFields Selectable[]

The transformations to apply.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

update(Update update)

public Pipeline update(Update update)

Performs an update operation using an Update stage.

This method allows you to use a pre-configured Update stage.

Example:


 Update updateStage = new Update().withTransformedFields(constant("Updated").as("status"));

 firestore.pipeline()
     .collection("books")
     .where(field("title").equal("The Hitchhiker's Guide to the Galaxy"))
     .update(updateStage)
     .execute()
     .get();
 
Parameter
Name Description
update Update

The Update stage to append.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.

where(BooleanExpression condition)

public Pipeline where(BooleanExpression condition)

Filters the documents from previous stages to only include those matching the specified BooleanExpression.

This stage allows you to apply conditions to the data, similar to a "WHERE" clause in SQL. You can filter documents based on their field values, using implementions of BooleanExpression, typically including but not limited to:

  • field comparators: FunctionExpression#equal, FunctionExpression#lessThan (less than), FunctionExpression#greaterThan (greater than), etc.
  • logical operators: FunctionExpression#and, FunctionExpression#or, FunctionExpression#not, etc.
  • advanced functions: FunctionExpression#regexMatch(String, String), FunctionExpression#arrayContains(Expression, Expression), etc.

Example:


 firestore.pipeline().collection("books")
   .where(
     and(
         gt("rating", 4.0),   // Filter for ratings greater than 4.0
         field("genre").eq("Science Fiction") // Equivalent to eq("genre", "Science Fiction")
     )
   );
 
Parameter
Name Description
condition BooleanExpression

The BooleanExpression to apply.

Returns
Type Description
Pipeline

A new Pipeline object with this stage appended to the stage list.