From b713b53cddf3eb9a333420d1151f9606bdba3ecb Mon Sep 17 00:00:00 2001 From: Morgan Chen Date: Fri, 31 Oct 2025 11:44:32 -0700 Subject: [PATCH 1/4] install prerelease firestore --- firestore/app/build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/firestore/app/build.gradle.kts b/firestore/app/build.gradle.kts index 645b2075..11de5e8d 100644 --- a/firestore/app/build.gradle.kts +++ b/firestore/app/build.gradle.kts @@ -46,7 +46,8 @@ dependencies { // Declare the dependency for the Cloud Firestore library // When using the BoM, you don't specify versions in Firebase library dependencies - implementation("com.google.firebase:firebase-firestore") + // implementation("com.google.firebase:firebase-firestore") + implementation("com.google.firebase:firebase-firestore:99.0.0-pipeline.preview.1") // Firebase / Play Services implementation("com.google.firebase:firebase-auth") From 4c5ad18d20929426d5bf86cbc28e5c7922020ad1 Mon Sep 17 00:00:00 2001 From: Morgan Chen Date: Fri, 31 Oct 2025 13:35:44 -0700 Subject: [PATCH 2/4] add pipeline snippets for android languages --- .../google/example/firestore/DocSnippets.java | 1369 +++++++++++++++++ .../example/firestore/kotlin/DocSnippets.kt | 1368 ++++++++++++++++ 2 files changed, 2737 insertions(+) diff --git a/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java b/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java index 1e179972..a0ad4336 100644 --- a/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java +++ b/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java @@ -53,6 +53,15 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import com.google.firebase.firestore.GeoPoint; +import com.google.firebase.firestore.Pipeline; +import com.google.firebase.firestore.PipelineSource; +import com.google.firebase.firestore.VectorValue; +import com.google.firebase.firestore.pipeline.AggregateFunction; +import com.google.firebase.firestore.pipeline.AggregateStage; +import com.google.firebase.firestore.pipeline.Expression; +import com.google.firebase.firestore.pipeline.SampleStage; +import com.google.firebase.firestore.pipeline.UnnestOptions; /** * Snippets for inclusion in documentation. @@ -1559,4 +1568,1364 @@ public void onComplete(@NonNull Task task) { }); // [END multi_aggregate_query] } + + // https://cloud.google.com/firestore/docs/pipeline/overview#concepts + void pipelineConcepts() { + // [START pipeline_concepts] + Pipeline pipeline = db.pipeline() + // Step 1: Start a query with collection scope + .collection("cities") + // Step 2: Filter the collection + .where(Expression.field("population").greaterThan(100000)) + // Step 3: Sort the remaining documents + .sort(Expression.field("name").ascending()) + // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have + // unintentional results. + .limit(10); + // [END pipeline_concepts] + System.out.println(pipeline); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#initialization + void pipelineInitialization() { + // [START pipeline_initialization] + FirebaseFirestore firestore = FirebaseFirestore.getInstance("enterprise"); + PipelineSource pipeline = firestore.pipeline(); + // [END pipeline_initialization] + System.out.println(pipeline); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#field_vs_constant_references/ + void fieldVsConstants() { + // [START field_or_constant] + Pipeline pipeline = db.pipeline() + .collection("cities") + .where(Expression.field("name").equal(Expression.constant("Toronto"))); + // [END field_or_constant] + System.out.println(pipeline); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#input_stages + void inputStages() { + // [START input_stages] + Task 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(); + // [END input_stages] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#where + void wherePipeline() { + // [START pipeline_where] + Task results; + + results = db.pipeline().collection("books") + .where(Expression.field("rating").equal(5)) + .where(Expression.field("published").lessThan(1900)) + .execute(); + + results = db.pipeline().collection("books") + .where(Expression.and( + Expression.field("rating").equal(5), + Expression.field("published").lessThan(1900) + )) + .execute(); + // [END pipeline_where] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#aggregate_distinct + void aggregateGroups() { + // [START aggregate_groups] + Task results = db.pipeline() + .collection("books") + .aggregate(AggregateStage + .withAccumulators( + AggregateFunction.average("rating").alias("avg_rating")) + .withGroups(Expression.field("genre"))) + .execute(); + // [END aggregate_groups] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#aggregate_distinct + void aggregateDistinct() { + // [START aggregate_distinct] + Task results = db.pipeline() + .collection("books") + .distinct( + Expression.field("author").toUpper().alias("author"), + Expression.field("genre") + ) + .execute(); + // [END aggregate_distinct] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#sort + void sort() { + // [START sort] + Task results = db.pipeline() + .collection("books") + .sort( + Expression.field("release_date").descending(), + Expression.field("author").ascending() + ) + .execute(); + // [END sort] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#sort + void sortComparison() { + // [START sort_comparison] + Query query = db.collection("cities") + .orderBy("state") + .orderBy("population", Query.Direction.DESCENDING); + + Pipeline pipeline = db.pipeline() + .collection("books") + .sort( + Expression.field("release_date").descending(), + Expression.field("author").ascending() + ); + // [END sort_comparison] + System.out.println(query); + System.out.println(pipeline); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#functions + void functions() { + // [START functions_example] + Task 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( + Expression.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(); + // [END functions_example] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#creating_indexes + void creatingIndexes() { + // [START query_example] + Task results = db.pipeline() + .collection("books") + .where(Expression.field("published").lessThan(1900)) + .where(Expression.field("genre").equal("Science Fiction")) + .where(Expression.field("rating").greaterThan(4.3)) + .sort(Expression.field("published").descending()) + .execute(); + // [END query_example] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#existing_sparse_indexes + void sparseIndexes() { + // [START sparse_index_example] + Task results = db.pipeline() + .collection("books") + .where(Expression.field("category").like("%fantasy%")) + .execute(); + // [END sparse_index_example] + System.out.println(results); + } + + void sparseIndexes2() { + // [START sparse_index_example_2] + Task results = db.pipeline() + .collection("books") + .sort(Expression.field("release_date").ascending()) + .execute(); + // [END sparse_index_example_2] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#covered_queries_secondary_indexes + void coveredQuery() { + // [START covered_query] + Task results = db.pipeline() + .collection("books") + .where(Expression.field("category").like("%fantasy%")) + .where(Expression.field("title").exists()) + .where(Expression.field("author").exists()) + .select(Expression.field("title"), Expression.field("author")) + .execute(); + // [END covered_query] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#pagination + void pagination() { + // [START pagination_not_supported_preview] + // 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(Expression.field("population").greaterThanOrEqual(1000000)) + .sort(Expression.field("population").descending()); + // [END pagination_not_supported_preview] + System.out.println(query); + System.out.println(pipeline); + } + + // http://cloud.google.com/firestore/docs/pipeline/stages/input/collection#example + void collectionStage() { + // [START collection_example] + Task results = db.pipeline() + .collection("users/bob/games") + .sort(Expression.field("name").ascending()) + .execute(); + // [END collection_example] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/input/collection_group + void collectionGroupStage() { + // [START collection_group_example] + Task results = db.pipeline() + .collectionGroup("games") + .sort(Expression.field("name").ascending()) + .execute(); + // [END collection_group_example] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/input/database + void databaseStage() { + // [START database_example] + // Count all documents in the database + Task results = db.pipeline() + .database() + .aggregate(AggregateFunction.countAll().alias("total")) + .execute(); + // [END database_example] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/input/documents + void documentsStage() { + // [START documents_example] + Task results = db.pipeline() + .documents( + db.collection("cities").document("SF"), + db.collection("cities").document("DC"), + db.collection("cities").document("NY") + ).execute(); + // [END documents_example] + System.out.println(results); + } + + void replaceWithStage() { + // [START initial_data] + db.collection("cities").document("SF").set(new HashMap() {{ + put("name", "San Francisco"); + put("population", 800000); + put("location", new HashMap() {{ + put("country", "USA"); + put("state", "California"); + }}); + }}); + db.collection("cities").document("TO").set(new HashMap() {{ + put("name", "Toronto"); + put("population", 3000000); + put("province", "ON"); + put("location", new HashMap() {{ + put("country", "Canada"); + put("province", "Ontario"); + }}); + }}); + db.collection("cities").document("NY").set(new HashMap() {{ + put("name", "New York"); + put("location", new HashMap() {{ + put("country", "USA"); + put("state", "New York"); + }}); + }}); + db.collection("cities").document("AT").set(new HashMap() {{ + put("name", "Atlantis"); + }}); + // [END initial_data] + + // [START full_replace] + Task names = db.pipeline() + .collection("cities") + .replaceWith("location") + .execute(); + // [END full_replace] + + // [START map_merge_overwrite] + // unsupported in client SDKs for now + // [END map_merge_overwrite] + System.out.println(names); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/sample#examples + void sampleStage() { + // [START sample_example] + Task results; + + // Get a sample of 100 documents in a database + results = db.pipeline() + .database() + .sample(100) + .execute(); + + // Randomly shuffle a list of 3 documents + results = db.pipeline() + .documents( + db.collection("cities").document("SF"), + db.collection("cities").document("NY"), + db.collection("cities").document("DC") + ) + .sample(3) + .execute(); + // [END sample_example] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/sample#examples_2 + void samplePercent() { + // [START sample_percent] + // Get a sample of on average 50% of the documents in the database + Task results = db.pipeline() + .database() + .sample(SampleStage.withPercentage(0.5)) + .execute(); + // [END sample_percent] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/union#examples + void unionStage() { + // [START union_stage] + Task results = db.pipeline() + .collection("cities/SF/restaurants") + .where(Expression.field("type").equal("Chinese")) + .union(db.pipeline() + .collection("cities/NY/restaurants") + .where(Expression.field("type").equal("Italian"))) + .where(Expression.field("rating").greaterThanOrEqual(4.5)) + .sort(Expression.field("__name__").descending()) + .execute(); + // [END union_stage] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/union#examples + void unionStageStable() { + // [START union_stage_stable] + Task results = db.pipeline() + .collection("cities/SF/restaurants") + .where(Expression.field("type").equal("Chinese")) + .union(db.pipeline() + .collection("cities/NY/restaurants") + .where(Expression.field("type").equal("Italian"))) + .where(Expression.field("rating").greaterThanOrEqual(4.5)) + .sort(Expression.field("__name__").descending()) + .execute(); + // [END union_stage_stable] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/unnest#examples + void unnestStage() { + // [START unnest_stage] + Task results = db.pipeline() + .database() + .unnest(Expression.field("arrayField").alias("unnestedArrayField"), new UnnestOptions().withIndexField("index")) + .execute(); + // [END unnest_stage] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/unnest#examples + void unnestStageEmptyOrNonArray() { + // [START unnest_edge_cases] + // Input + // { identifier : 1, neighbors: [ "Alice", "Cathy" ] } + // { identifier : 2, neighbors: [] } + // { identifier : 3, neighbors: "Bob" } + + Task results = db.pipeline() + .database() + .unnest(Expression.field("neighbors").alias("unnestedNeighbors"), new UnnestOptions().withIndexField("index")) + .execute(); + + // Output + // { identifier: 1, neighbors: [ "Alice", "Cathy" ], unnestedNeighbors: "Alice", index: 0 } + // { identifier: 1, neighbors: [ "Alice", "Cathy" ], unnestedNeighbors: "Cathy", index: 1 } + // { identifier: 3, neighbors: "Bob", index: null} + // [END unnest_edge_cases] + System.out.println(results); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#count + void countFunction() { + // [START count_function] + // Total number of books in the collection + Task countAll = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.countAll().alias("count")) + .execute(); + + // Number of books with nonnull `ratings` field + Task countField = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.count("ratings").alias("count")) + .execute(); + // [END count_function] + System.out.println(countAll); + System.out.println(countField); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#count_if + void countIfFunction() { + // [START count_if] + Task result = db.pipeline() + .collection("books") + .aggregate( + AggregateFunction.countIf(Expression.field("rating").greaterThan(4)).alias("filteredCount") + ) + .execute(); + // [END count_if] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#count_distinct + void countDistinctFunction() { + // [START count_distinct] + Task result = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.countDistinct("author").alias("unique_authors")) + .execute(); + // [END count_distinct] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#sum + void sumFunction() { + // [START sum_function] + Task result = db.pipeline() + .collection("cities") + .aggregate(AggregateFunction.sum("population").alias("totalPopulation")) + .execute(); + // [END sum_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#avg + void avgFunction() { + // [START avg_function] + Task result = db.pipeline() + .collection("cities") + .aggregate(AggregateFunction.average("population").alias("averagePopulation")) + .execute(); + // [END avg_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#min + void minFunction() { + // [START min_function] + Task result = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.minimum("price").alias("minimumPrice")) + .execute(); + // [END min_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#max + void maxFunction() { + // [START max_function] + Task result = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.maximum("price").alias("maximumPrice")) + .execute(); + // [END max_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#add + void addFunction() { + // [START add_function] + Task result = db.pipeline() + .collection("books") + .select(Expression.add(Expression.field("soldBooks"), Expression.field("unsoldBooks")).alias("totalBooks")) + .execute(); + // [END add_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#subtract + void subtractFunction() { + // [START subtract_function] + int storeCredit = 7; + Task result = db.pipeline() + .collection("books") + .select(Expression.subtract(Expression.field("price"), storeCredit).alias("totalCost")) + .execute(); + // [END subtract_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#multiply + void multiplyFunction() { + // [START multiply_function] + Task result = db.pipeline() + .collection("books") + .select(Expression.multiply(Expression.field("price"), Expression.field("soldBooks")).alias("revenue")) + .execute(); + // [END multiply_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#divide + void divideFunction() { + // [START divide_function] + Task result = db.pipeline() + .collection("books") + .select(Expression.divide(Expression.field("ratings"), Expression.field("soldBooks")).alias("reviewRate")) + .execute(); + // [END divide_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#mod + void modFunction() { + // [START mod_function] + int displayCapacity = 1000; + Task result = db.pipeline() + .collection("books") + .select(Expression.mod(Expression.field("unsoldBooks"), displayCapacity).alias("warehousedBooks")) + .execute(); + // [END mod_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#ceil + void ceilFunction() { + // [START ceil_function] + int booksPerShelf = 100; + Task result = db.pipeline() + .collection("books") + .select( + Expression.divide(Expression.field("unsoldBooks"), booksPerShelf).ceil().alias("requiredShelves") + ) + .execute(); + // [END ceil_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#floor + void floorFunction() { + // [START floor_function] + Task result = db.pipeline() + .collection("books") + .addFields( + Expression.divide(Expression.field("wordCount"), Expression.field("pages")).floor().alias("wordsPerPage") + ) + .execute(); + // [END floor_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#round + void roundFunction() { + // [START round_function] + Task result = db.pipeline() + .collection("books") + .select(Expression.multiply(Expression.field("soldBooks"), Expression.field("price")).round().alias("partialRevenue")) + .aggregate(AggregateFunction.sum("partialRevenue").alias("totalRevenue")) + .execute(); + // [END round_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#pow + void powFunction() { + // [START pow_function] + GeoPoint googleplex = new GeoPoint(37.4221, -122.0853); + Task result = db.pipeline() + .collection("cities") + .addFields( + Expression.field("lat").subtract(googleplex.getLatitude()) + .multiply(111 /* km per degree */) + .pow(2) + .alias("latitudeDifference"), + Expression.field("lng").subtract(googleplex.getLongitude()) + .multiply(111 /* km per degree */) + .pow(2) + .alias("longitudeDifference") + ) + .select( + Expression.field("latitudeDifference").add(Expression.field("longitudeDifference")).sqrt() + // Inaccurate for large distances or close to poles + .alias("approximateDistanceToGoogle") + ) + .execute(); + // [END pow_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#sqrt + void sqrtFunction() { + // [START sqrt_function] + GeoPoint googleplex = new GeoPoint(37.4221, -122.0853); + Task result = db.pipeline() + .collection("cities") + .addFields( + Expression.field("lat").subtract(googleplex.getLatitude()) + .multiply(111 /* km per degree */) + .pow(2) + .alias("latitudeDifference"), + Expression.field("lng").subtract(googleplex.getLongitude()) + .multiply(111 /* km per degree */) + .pow(2) + .alias("longitudeDifference") + ) + .select( + Expression.field("latitudeDifference").add(Expression.field("longitudeDifference")).sqrt() + // Inaccurate for large distances or close to poles + .alias("approximateDistanceToGoogle") + ) + .execute(); + // [END sqrt_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#exp + void expFunction() { + // [START exp_function] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("rating").exp().alias("expRating")) + .execute(); + // [END exp_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#ln + void lnFunction() { + // [START ln_function] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("rating").ln().alias("lnRating")) + .execute(); + // [END ln_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#log + void logFunction() { + // [START log_function] + // Not supported on Android + // [END log_function] + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_concat + void arrayConcat() { + // [START array_concat] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("genre").arrayConcat(Expression.field("subGenre")).alias("allGenres")) + .execute(); + // [END array_concat] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_contains + void arrayContains() { + // [START array_contains] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("genre").arrayContains("mystery").alias("isMystery")) + .execute(); + // [END array_contains] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_contains_all + void arrayContainsAll() { + // [START array_contains_all] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("genre") + .arrayContainsAll(Arrays.asList("fantasy", "adventure")) + .alias("isFantasyAdventure") + ) + .execute(); + // [END array_contains_all] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_contains_any + void arrayContainsAny() { + // [START array_contains_any] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("genre") + .arrayContainsAny(Arrays.asList("fantasy", "nonfiction")) + .alias("isMysteryOrFantasy") + ) + .execute(); + // [END array_contains_any] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_length + void arrayLength() { + // [START array_length] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("genre").arrayLength().alias("genreCount")) + .execute(); + // [END array_length] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_reverse + void arrayReverse() { + // [START array_reverse] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("genre").arrayReverse().alias("reversedGenres")) + .execute(); + // [END array_reverse] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#eq + void equalFunction() { + // [START equal_function] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("rating").equal(5).alias("hasPerfectRating")) + .execute(); + // [END equal_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#gt + void greaterThanFunction() { + // [START greater_than] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("rating").greaterThan(4).alias("hasHighRating")) + .execute(); + // [END greater_than] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#gte + void greaterThanOrEqualToFunction() { + // [START greater_or_equal] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("published").greaterThanOrEqual(1900).alias("publishedIn20thCentury")) + .execute(); + // [END greater_or_equal] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#lt + void lessThanFunction() { + // [START less_than] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("published").lessThan(1923).alias("isPublicDomainProbably")) + .execute(); + // [END less_than] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#lte + void lessThanOrEqualToFunction() { + // [START less_or_equal] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("rating").lessThanOrEqual(2).alias("hasBadRating")) + .execute(); + // [END less_or_equal] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#neq + void notEqualFunction() { + // [START not_equal] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("title").notEqual("1984").alias("not1984")) + .execute(); + // [END not_equal] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/debugging_functions#exists + void existsFunction() { + // [START exists_function] + Task result = db.pipeline() + .collection("books") + .select(Expression.field("rating").exists().alias("hasRating")) + .execute(); + // [END exists_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#and + void andFunction() { + // [START and_function] + Task result = db.pipeline() + .collection("books") + .select( + Expression.and( + Expression.field("rating").greaterThan(4), + Expression.field("price").lessThan(10) + ).alias("under10Recommendation") + ) + .execute(); + // [END and_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#or + void orFunction() { + // [START or_function] + Task result = db.pipeline() + .collection("books") + .select( + Expression.or( + Expression.field("genre").equal("Fantasy"), + Expression.field("tags").arrayContains("adventure") + ).alias("matchesSearchFilters") + ) + .execute(); + // [END or_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#xor + void xorFunction() { + // [START xor_function] + Task result = db.pipeline() + .collection("books") + .select( + Expression.xor( + Expression.field("tags").arrayContains("magic"), + Expression.field("tags").arrayContains("nonfiction") + ).alias("matchesSearchFilters") + ) + .execute(); + // [END xor_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#not + void notFunction() { + // [START not_function] + Task result = db.pipeline() + .collection("books") + .select( + Expression.not( + Expression.field("tags").arrayContains("nonfiction") + ).alias("isFiction") + ) + .execute(); + // [END not_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#cond + void condFunction() { + // [START cond_function] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("tags").arrayConcat( + Expression.conditional( + Expression.field("pages").greaterThan(100), + Expression.constant("longRead"), + Expression.constant("shortRead") + ) + ).alias("extendedTags") + ) + .execute(); + // [END cond_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#eq_any + void equalAnyFunction() { + // [START eq_any] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("genre").equalAny(Arrays.asList("Science Fiction", "Psychological Thriller")) + .alias("matchesGenreFilters") + ) + .execute(); + // [END eq_any] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#not_eq_any + void notEqualAnyFunction() { + // [START not_eq_any] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("author").notEqualAny(Arrays.asList("George Orwell", "F. Scott Fitzgerald")) + .alias("byExcludedAuthors") + ) + .execute(); + // [END not_eq_any] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#is_nan + void isNaNFunction() { + // [START is_nan] + // removed + // [END is_nan] + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#is_not_nan + void isNotNaNFunction() { + // [START is_not_nan] + // removed + // [END is_not_nan] + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#max + void maxLogicalFunction() { + // [START max_logical_function] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("rating").logicalMaximum(1).alias("flooredRating") + ) + .execute(); + // [END max_logical_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#min + void minLogicalFunction() { + // [START min_logical_function] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("rating").logicalMinimum(5).alias("cappedRating") + ) + .execute(); + // [END min_logical_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/map_functions#map_get + void mapGetFunction() { + // [START map_get] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("awards").mapGet("pulitzer").alias("hasPulitzerAward") + ) + .execute(); + // [END map_get] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#byte_length + void byteLengthFunction() { + // [START byte_length] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("title").byteLength().alias("titleByteLength") + ) + .execute(); + // [END byte_length] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#char_length + void charLengthFunction() { + // [START char_length] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("title").charLength().alias("titleCharLength") + ) + .execute(); + // [END char_length] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#starts_with + void startsWithFunction() { + // [START starts_with] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("title").startsWith("The") + .alias("needsSpecialAlphabeticalSort") + ) + .execute(); + // [END starts_with] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#ends_with + void endsWithFunction() { + // [START ends_with] + Task result = db.pipeline() + .collection("inventory/devices/laptops") + .select( + Expression.field("name").endsWith("16 inch") + .alias("16InLaptops") + ) + .execute(); + // [END ends_with] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#like + void likeFunction() { + // [START like] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("genre").like("%Fiction") + .alias("anyFiction") + ) + .execute(); + // [END like] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#regex_contains + void regexContainsFunction() { + // [START regex_contains] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("title").regexContains("Firestore (Enterprise|Standard)") + .alias("isFirestoreRelated") + ) + .execute(); + // [END regex_contains] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#regex_match + void regexMatchFunction() { + // [START regex_match] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("title").regexMatch("Firestore (Enterprise|Standard)") + .alias("isFirestoreExactly") + ) + .execute(); + // [END regex_match] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_concat + void strConcatFunction() { + // [START str_concat] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("title").concat(" by ", Expression.field("author")) + .alias("fullyQualifiedTitle") + ) + .execute(); + // [END str_concat] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_contains + void strContainsFunction() { + // [START string_contains] + Task result = db.pipeline() + .collection("articles") + .select( + Expression.field("body").stringContains("Firestore") + .alias("isFirestoreRelated") + ) + .execute(); + // [END string_contains] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#to_upper + void toUpperFunction() { + // [START to_upper] + Task result = db.pipeline() + .collection("authors") + .select( + Expression.field("name").toUpper() + .alias("uppercaseName") + ) + .execute(); + // [END to_upper] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#to_lower + void toLowerFunction() { + // [START to_lower] + Task result = db.pipeline() + .collection("authors") + .select( + Expression.field("genre").toLower().equal("fantasy") + .alias("isFantasy") + ) + .execute(); + // [END to_lower] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#substr + void substrFunction() { + // [START substr_function] + Task result = db.pipeline() + .collection("books") + .where(Expression.field("title").startsWith("The ")) + .select( + Expression.field("title").substring( + Expression.constant(4), + Expression.field("title").charLength().subtract(4)) + .alias("titleWithoutLeadingThe") + ) + .execute(); + // [END substr_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_reverse + void strReverseFunction() { + // [START str_reverse] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("name").reverse().alias("reversedName") + ) + .execute(); + // [END str_reverse] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_trim + void strTrimFunction() { + // [START trim_function] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("name").trim().alias("whitespaceTrimmedName") + ) + .execute(); + // [END trim_function] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_replace + void strReplaceFunction() { + // not yet supported until GA + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_split + void strSplitFunction() { + // not yet supported until GA + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#unix_micros_to_timestamp + void unixMicrosToTimestampFunction() { + // [START unix_micros_timestamp] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("createdAtMicros").unixMicrosToTimestamp().alias("createdAtString") + ) + .execute(); + // [END unix_micros_timestamp] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#unix_millis_to_timestamp + void unixMillisToTimestampFunction() { + // [START unix_millis_timestamp] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("createdAtMillis").unixMillisToTimestamp().alias("createdAtString") + ) + .execute(); + // [END unix_millis_timestamp] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#unix_seconds_to_timestamp + void unixSecondsToTimestampFunction() { + // [START unix_seconds_timestamp] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("createdAtSeconds").unixSecondsToTimestamp().alias("createdAtString") + ) + .execute(); + // [END unix_seconds_timestamp] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_add + void timestampAddFunction() { + // [START timestamp_add] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("createdAt").timestampAdd("day", 3653).alias("expiresAt") + ) + .execute(); + // [END timestamp_add] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_sub + void timestampSubFunction() { + // [START timestamp_sub] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("expiresAt").timestampSubtract("day", 14).alias("sendWarningTimestamp") + ) + .execute(); + // [END timestamp_sub] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_to_unix_micros + void timestampToUnixMicrosFunction() { + // [START timestamp_unix_micros] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("dateString").timestampToUnixMicros().alias("unixMicros") + ) + .execute(); + // [END timestamp_unix_micros] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_to_unix_millis + void timestampToUnixMillisFunction() { + // [START timestamp_unix_millis] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("dateString").timestampToUnixMillis().alias("unixMillis") + ) + .execute(); + // [END timestamp_unix_millis] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_to_unix_seconds + void timestampToUnixSecondsFunction() { + // [START timestamp_unix_seconds] + Task result = db.pipeline() + .collection("documents") + .select( + Expression.field("dateString").timestampToUnixSeconds().alias("unixSeconds") + ) + .execute(); + // [END timestamp_unix_seconds] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/vector_functions#cosine_distance + void cosineDistanceFunction() { + // [START cosine_distance] + double[] sampleVector = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0}; + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("embedding").cosineDistance(sampleVector).alias("cosineDistance") + ) + .execute(); + // [END cosine_distance] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/vector_functions#dot_product + void dotProductFunction() { + // [START dot_product] + double[] sampleVector = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0}; + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("embedding").dotProduct(sampleVector).alias("dotProduct") + ) + .execute(); + // [END dot_product] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/vector_functions#euclidean_distance + void euclideanDistanceFunction() { + // [START euclidean_distance] + double[] sampleVector = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0}; + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("embedding").euclideanDistance(sampleVector).alias("euclideanDistance") + ) + .execute(); + // [END euclidean_distance] + System.out.println(result); + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/vector_functions#vector_length + void vectorLengthFunction() { + // [START vector_length] + Task result = db.pipeline() + .collection("books") + .select( + Expression.field("embedding").vectorLength().alias("vectorLength") + ) + .execute(); + // [END vector_length] + System.out.println(result); + } } diff --git a/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt b/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt index de23a75e..9e38e7f8 100644 --- a/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt +++ b/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt @@ -28,6 +28,14 @@ import java.util.HashMap import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.ThreadPoolExecutor import java.util.concurrent.TimeUnit +import com.google.android.gms.tasks.Task +import com.google.firebase.firestore.GeoPoint +import com.google.firebase.firestore.Pipeline +import com.google.firebase.firestore.pipeline.AggregateFunction +import com.google.firebase.firestore.pipeline.AggregateStage +import com.google.firebase.firestore.pipeline.Expression +import com.google.firebase.firestore.pipeline.SampleStage +import com.google.firebase.firestore.pipeline.UnnestOptions /** * Kotlin version of doc snippets. @@ -1317,4 +1325,1364 @@ abstract class DocSnippets(val db: FirebaseFirestore) { } // [END multi_aggregate_query] } + + // https://cloud.google.com/firestore/docs/pipeline/overview#concepts + fun pipelineConcepts() { + // [START pipeline_concepts] + val pipeline = db.pipeline() + // Step 1: Start a query with collection scope + .collection("cities") + // Step 2: Filter the collection + .where(Expression.field("population").greaterThan(100000)) + // Step 3: Sort the remaining documents + .sort(Expression.field("name").ascending()) + // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have + // unintentional results. + .limit(10) + // [END pipeline_concepts] + println(pipeline) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#initialization + fun pipelineInitialization() { + // [START pipeline_initialization] + val firestore = Firebase.firestore("enterprise") + val pipeline = firestore.pipeline() + // [END pipeline_initialization] + println(pipeline) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#field_vs_constant_references/ + fun fieldVsConstants() { + // [START field_or_constant] + val pipeline = db.pipeline() + .collection("cities") + .where(Expression.field("name").equal(Expression.constant("Toronto"))) + // [END field_or_constant] + println(pipeline) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#input_stages + fun inputStages() { + // [START input_stages] + var results: Task + + // 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() + // [END input_stages] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#where + fun wherePipeline() { + // [START pipeline_where] + var results: Task + + results = db.pipeline().collection("books") + .where(Expression.field("rating").equal(5)) + .where(Expression.field("published").lessThan(1900)) + .execute() + + results = db.pipeline().collection("books") + .where(Expression.and(Expression.field("rating").equal(5), + Expression.field("published").lessThan(1900))) + .execute() + // [END pipeline_where] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#aggregate_distinct + fun aggregateGroups() { + // [START aggregate_groups] + val results = db.pipeline() + .collection("books") + .aggregate( + AggregateStage + .withAccumulators(AggregateFunction.average("rating").alias("avg_rating")) + .withGroups(Expression.field("genre")) + ) + .execute() + // [END aggregate_groups] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#aggregate_distinct + fun aggregateDistinct() { + // [START aggregate_distinct] + val results = db.pipeline() + .collection("books") + .distinct( + Expression.field("author").toUpper().alias("author"), + Expression.field("genre") + ) + .execute() + // [END aggregate_distinct] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#sort + fun sort() { + // [START sort] + val results = db.pipeline() + .collection("books") + .sort( + Expression.field("release_date").descending(), + Expression.field("author").ascending() + ) + .execute() + // [END sort] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#sort + fun sortComparison() { + // [START sort_comparison] + val query = db.collection("cities") + .orderBy("state") + .orderBy("population", Query.Direction.DESCENDING) + + val pipeline = db.pipeline() + .collection("books") + .sort( + Expression.field("release_date").descending(), + Expression.field("author").ascending() + ) + // [END sort_comparison] + println(query) + println(pipeline) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#functions + fun functions() { + // [START functions_example] + var results: Task + + // Type 1: Scalar (for use in non-aggregation stages) + // Example: Return the min store price for each book. + results = db.pipeline().collection("books") + .select( + Expression.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() + // [END functions_example] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#creating_indexes + fun creatingIndexes() { + // [START query_example] + val results = db.pipeline() + .collection("books") + .where(Expression.field("published").lessThan(1900)) + .where(Expression.field("genre").equal("Science Fiction")) + .where(Expression.field("rating").greaterThan(4.3)) + .sort(Expression.field("published").descending()) + .execute() + // [END query_example] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#existing_sparse_indexes + fun sparseIndexes() { + // [START sparse_index_example] + val results = db.pipeline() + .collection("books") + .where(Expression.field("category").like("%fantasy%")) + .execute() + // [END sparse_index_example] + println(results) + } + + fun sparseIndexes2() { + // [START sparse_index_example_2] + val results = db.pipeline() + .collection("books") + .sort(Expression.field("release_date").ascending()) + .execute() + // [END sparse_index_example_2] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#covered_queries_secondary_indexes + fun coveredQuery() { + // [START covered_query] + val results = db.pipeline() + .collection("books") + .where(Expression.field("category").like("%fantasy%")) + .where(Expression.field("title").exists()) + .where(Expression.field("author").exists()) + .select(Expression.field("title"), Expression.field("author")) + .execute() + // [END covered_query] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#pagination + fun pagination() { + // [START pagination_not_supported_preview] + // 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(Expression.field("population").greaterThanOrEqual(1000000)) + .sort(Expression.field("population").descending()) + // [END pagination_not_supported_preview] + println(query) + println(pipeline) + } + + // http://cloud.google.com/firestore/docs/pipeline/stages/input/collection#example + fun collectionStage() { + // [START collection_example] + val results = db.pipeline() + .collection("users/bob/games") + .sort(Expression.field("name").ascending()) + .execute() + // [END collection_example] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/input/collection_group + fun collectionGroupStage() { + // [START collection_group_example] + val results = db.pipeline() + .collectionGroup("games") + .sort(Expression.field("name").ascending()) + .execute() + // [END collection_group_example] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/input/database + fun databaseStage() { + // [START database_example] + // Count all documents in the database + val results = db.pipeline() + .database() + .aggregate(AggregateFunction.countAll().alias("total")) + .execute() + // [END database_example] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/input/documents + fun documentsStage() { + // [START documents_example] + val results = db.pipeline() + .documents( + db.collection("cities").document("SF"), + db.collection("cities").document("DC"), + db.collection("cities").document("NY") + ).execute() + // [END documents_example] + println(results) + } + + fun replaceWithStage() { + // [START initial_data] + db.collection("cities").document("SF").set(mapOf( + "name" to "San Francisco", + "population" to 800000, + "location" to mapOf( + "country" to "USA", + "state" to "California" + ) + )) + db.collection("cities").document("TO").set(mapOf( + "name" to "Toronto", + "population" to 3000000, + "province" to "ON", + "location" to mapOf( + "country" to "Canada", + "province" to "Ontario" + ) + )) + db.collection("cities").document("NY").set(mapOf( + "name" to "New York", + "location" to mapOf( + "country" to "USA", + "state" to "New York" + ) + )) + db.collection("cities").document("AT").set(mapOf( + "name" to "Atlantis" + )) + // [END initial_data] + + // [START full_replace] + val names = db.pipeline() + .collection("cities") + .replaceWith("location") + .execute() + // [END full_replace] + + // [START map_merge_overwrite] + // unsupported in client SDKs for now + // [END map_merge_overwrite] + println(names) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/sample#examples + fun sampleStage() { + // [START sample_example] + var results: Task + + // Get a sample of 100 documents in a database + results = db.pipeline() + .database() + .sample(100) + .execute() + + // Randomly shuffle a list of 3 documents + results = db.pipeline() + .documents( + db.collection("cities").document("SF"), + db.collection("cities").document("NY"), + db.collection("cities").document("DC") + ) + .sample(3) + .execute() + // [END sample_example] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/sample#examples_2 + fun samplePercent() { + // [START sample_percent] + // Get a sample of on average 50% of the documents in the database + val results = db.pipeline() + .database() + .sample(SampleStage.withPercentage(0.5)) + .execute() + // [END sample_percent] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/union#examples + fun unionStage() { + // [START union_stage] + val results = db.pipeline() + .collection("cities/SF/restaurants") + .where(Expression.field("type").equal("Chinese")) + .union(db.pipeline() + .collection("cities/NY/restaurants") + .where(Expression.field("type").equal("Italian"))) + .where(Expression.field("rating").greaterThanOrEqual(4.5)) + .sort(Expression.field("__name__").descending()) + .execute() + // [END union_stage] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/union#examples + fun unionStageStable() { + // [START union_stage_stable] + val results = db.pipeline() + .collection("cities/SF/restaurants") + .where(Expression.field("type").equal("Chinese")) + .union(db.pipeline() + .collection("cities/NY/restaurants") + .where(Expression.field("type").equal("Italian"))) + .where(Expression.field("rating").greaterThanOrEqual(4.5)) + .sort(Expression.field("__name__").descending()) + .execute() + // [END union_stage_stable] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/unnest#examples + fun unnestStage() { + // [START unnest_stage] + val results = db.pipeline() + .database() + .unnest(Expression.field("arrayField").alias("unnestedArrayField"), UnnestOptions().withIndexField("index")) + .execute() + // [END unnest_stage] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/stages/transformation/unnest#examples + fun unnestStageEmptyOrNonArray() { + // [START unnest_edge_cases] + // Input + // { identifier : 1, neighbors: [ "Alice", "Cathy" ] } + // { identifier : 2, neighbors: [] } + // { identifier : 3, neighbors: "Bob" } + + val results = db.pipeline() + .database() + .unnest(Expression.field("neighbors").alias("unnestedNeighbors"), UnnestOptions().withIndexField("index")) + .execute() + + // Output + // { identifier: 1, neighbors: [ "Alice", "Cathy" ], unnestedNeighbors: "Alice", index: 0 } + // { identifier: 1, neighbors: [ "Alice", "Cathy" ], unnestedNeighbors: "Cathy", index: 1 } + // { identifier: 3, neighbors: "Bob", index: null} + // [END unnest_edge_cases] + println(results) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#count + fun countFunction() { + // [START count_function] + // Total number of books in the collection + val countAll = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.countAll().alias("count")) + .execute() + + // Number of books with nonnull `ratings` field + val countField = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.count("ratings").alias("count")) + .execute() + // [END count_function] + println(countAll) + println(countField) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#count_if + fun countIfFunction() { + // [START count_if] + val result = db.pipeline() + .collection("books") + .aggregate( + AggregateFunction.countIf(Expression.field("rating").greaterThan(4)).alias("filteredCount") + ) + .execute() + // [END count_if] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#count_distinct + fun countDistinctFunction() { + // [START count_distinct] + val result = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.countDistinct("author").alias("unique_authors")) + .execute() + // [END count_distinct] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#sum + fun sumFunction() { + // [START sum_function] + val result = db.pipeline() + .collection("cities") + .aggregate(AggregateFunction.sum("population").alias("totalPopulation")) + .execute() + // [END sum_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#avg + fun avgFunction() { + // [START avg_function] + val result = db.pipeline() + .collection("cities") + .aggregate(AggregateFunction.average("population").alias("averagePopulation")) + .execute() + // [END avg_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#min + fun minFunction() { + // [START min_function] + val result = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.minimum("price").alias("minimumPrice")) + .execute() + // [END min_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/aggregate_functions#max + fun maxFunction() { + // [START max_function] + val result = db.pipeline() + .collection("books") + .aggregate(AggregateFunction.maximum("price").alias("maximumPrice")) + .execute() + // [END max_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#add + fun addFunction() { + // [START add_function] + val result = db.pipeline() + .collection("books") + .select(Expression.add(Expression.field("soldBooks"), Expression.field("unsoldBooks")).alias("totalBooks")) + .execute() + // [END add_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#subtract + fun subtractFunction() { + // [START subtract_function] + val storeCredit = 7 + val result = db.pipeline() + .collection("books") + .select(Expression.subtract(Expression.field("price"), storeCredit).alias("totalCost")) + .execute() + // [END subtract_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#multiply + fun multiplyFunction() { + // [START multiply_function] + val result = db.pipeline() + .collection("books") + .select(Expression.multiply(Expression.field("price"), Expression.field("soldBooks")).alias("revenue")) + .execute() + // [END multiply_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#divide + fun divideFunction() { + // [START divide_function] + val result = db.pipeline() + .collection("books") + .select(Expression.divide(Expression.field("ratings"), Expression.field("soldBooks")).alias("reviewRate")) + .execute() + // [END divide_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#mod + fun modFunction() { + // [START mod_function] + val displayCapacity = 1000 + val result = db.pipeline() + .collection("books") + .select(Expression.mod(Expression.field("unsoldBooks"), displayCapacity).alias("warehousedBooks")) + .execute() + // [END mod_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#ceil + fun ceilFunction() { + // [START ceil_function] + val booksPerShelf = 100 + val result = db.pipeline() + .collection("books") + .select( + Expression.divide(Expression.field("unsoldBooks"), booksPerShelf).ceil().alias("requiredShelves") + ) + .execute() + // [END ceil_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#floor + fun floorFunction() { + // [START floor_function] + val result = db.pipeline() + .collection("books") + .addFields( + Expression.divide(Expression.field("wordCount"), Expression.field("pages")).floor().alias("wordsPerPage") + ) + .execute() + // [END floor_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#round + fun roundFunction() { + // [START round_function] + val result = db.pipeline() + .collection("books") + .select(Expression.multiply(Expression.field("soldBooks"), Expression.field("price")).round().alias("partialRevenue")) + .aggregate(AggregateFunction.sum("partialRevenue").alias("totalRevenue")) + .execute() + // [END round_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#pow + fun powFunction() { + // [START pow_function] + val googleplex = GeoPoint(37.4221, -122.0853) + val result = db.pipeline() + .collection("cities") + .addFields( + Expression.field("lat").subtract(googleplex.latitude) + .multiply(111 /* km per degree */) + .pow(2) + .alias("latitudeDifference"), + Expression.field("lng").subtract(googleplex.longitude) + .multiply(111 /* km per degree */) + .pow(2) + .alias("longitudeDifference") + ) + .select( + Expression.field("latitudeDifference").add(Expression.field("longitudeDifference")).sqrt() + // Inaccurate for large distances or close to poles + .alias("approximateDistanceToGoogle") + ) + .execute() + // [END pow_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#sqrt + fun sqrtFunction() { + // [START sqrt_function] + val googleplex = GeoPoint(37.4221, -122.0853) + val result = db.pipeline() + .collection("cities") + .addFields( + Expression.field("lat").subtract(googleplex.latitude) + .multiply(111 /* km per degree */) + .pow(2) + .alias("latitudeDifference"), + Expression.field("lng").subtract(googleplex.longitude) + .multiply(111 /* km per degree */) + .pow(2) + .alias("longitudeDifference") + ) + .select( + Expression.field("latitudeDifference").add(Expression.field("longitudeDifference")).sqrt() + // Inaccurate for large distances or close to poles + .alias("approximateDistanceToGoogle") + ) + .execute() + // [END sqrt_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#exp + fun expFunction() { + // [START exp_function] + val result = db.pipeline() + .collection("books") + .select(Expression.field("rating").exp().alias("expRating")) + .execute() + // [END exp_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#ln + fun lnFunction() { + // [START ln_function] + val result = db.pipeline() + .collection("books") + .select(Expression.field("rating").ln().alias("lnRating")) + .execute() + // [END ln_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/arithmetic_functions#log + fun logFunction() { + // [START log_function] + // Not supported on Android + // [END log_function] + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_concat + fun arrayConcat() { + // [START array_concat] + val result = db.pipeline() + .collection("books") + .select(Expression.field("genre").arrayConcat(Expression.field("subGenre")).alias("allGenres")) + .execute() + // [END array_concat] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_contains + fun arrayContains() { + // [START array_contains] + val result = db.pipeline() + .collection("books") + .select(Expression.field("genre").arrayContains("mystery").alias("isMystery")) + .execute() + // [END array_contains] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_contains_all + fun arrayContainsAll() { + // [START array_contains_all] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("genre") + .arrayContainsAll(listOf("fantasy", "adventure")) + .alias("isFantasyAdventure") + ) + .execute() + // [END array_contains_all] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_contains_any + fun arrayContainsAny() { + // [START array_contains_any] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("genre") + .arrayContainsAny(listOf("fantasy", "nonfiction")) + .alias("isMysteryOrFantasy") + ) + .execute() + // [END array_contains_any] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_length + fun arrayLength() { + // [START array_length] + val result = db.pipeline() + .collection("books") + .select(Expression.field("genre").arrayLength().alias("genreCount")) + .execute() + // [END array_length] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/array_functions#array_reverse + fun arrayReverse() { + // [START array_reverse] + val result = db.pipeline() + .collection("books") + .select(Expression.field("genre").arrayReverse().alias("reversedGenres")) + .execute() + // [END array_reverse] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#eq + fun equalFunction() { + // [START equal_function] + val result = db.pipeline() + .collection("books") + .select(Expression.field("rating").equal(5).alias("hasPerfectRating")) + .execute() + // [END equal_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#gt + fun greaterThanFunction() { + // [START greater_than] + val result = db.pipeline() + .collection("books") + .select(Expression.field("rating").greaterThan(4).alias("hasHighRating")) + .execute() + // [END greater_than] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#gte + fun greaterThanOrEqualToFunction() { + // [START greater_or_equal] + val result = db.pipeline() + .collection("books") + .select(Expression.field("published").greaterThanOrEqual(1900).alias("publishedIn20thCentury")) + .execute() + // [END greater_or_equal] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#lt + fun lessThanFunction() { + // [START less_than] + val result = db.pipeline() + .collection("books") + .select(Expression.field("published").lessThan(1923).alias("isPublicDomainProbably")) + .execute() + // [END less_than] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#lte + fun lessThanOrEqualToFunction() { + // [START less_or_equal] + val result = db.pipeline() + .collection("books") + .select(Expression.field("rating").lessThanOrEqual(2).alias("hasBadRating")) + .execute() + // [END less_or_equal] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/comparison_functions#neq + fun notEqualFunction() { + // [START not_equal] + val result = db.pipeline() + .collection("books") + .select(Expression.field("title").notEqual("1984").alias("not1984")) + .execute() + // [END not_equal] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/debugging_functions#exists + fun existsFunction() { + // [START exists_function] + val result = db.pipeline() + .collection("books") + .select(Expression.field("rating").exists().alias("hasRating")) + .execute() + // [END exists_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#and + fun andFunction() { + // [START and_function] + val result = db.pipeline() + .collection("books") + .select( + Expression.and(Expression.field("rating").greaterThan(4), + Expression.field("price").lessThan(10)) + .alias("under10Recommendation") + ) + .execute() + // [END and_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#or + fun orFunction() { + // [START or_function] + val result = db.pipeline() + .collection("books") + .select( + Expression.or(Expression.field("genre").equal("Fantasy"), + Expression.field("tags").arrayContains("adventure")) + .alias("matchesSearchFilters") + ) + .execute() + // [END or_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#xor + fun xorFunction() { + // [START xor_function] + val result = db.pipeline() + .collection("books") + .select( + Expression.xor(Expression.field("tags").arrayContains("magic"), + Expression.field("tags").arrayContains("nonfiction")) + .alias("matchesSearchFilters") + ) + .execute() + // [END xor_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#not + fun notFunction() { + // [START not_function] + val result = db.pipeline() + .collection("books") + .select( + Expression.not( + Expression.field("tags").arrayContains("nonfiction") + ).alias("isFiction") + ) + .execute() + // [END not_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#cond + fun condFunction() { + // [START cond_function] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("tags").arrayConcat( + Expression.conditional( + Expression.field("pages").greaterThan(100), + Expression.constant("longRead"), + Expression.constant("shortRead") + ) + ).alias("extendedTags") + ) + .execute() + // [END cond_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#eq_any + fun equalAnyFunction() { + // [START eq_any] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("genre").equalAny(listOf("Science Fiction", "Psychological Thriller")) + .alias("matchesGenreFilters") + ) + .execute() + // [END eq_any] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#not_eq_any + fun notEqualAnyFunction() { + // [START not_eq_any] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("author").notEqualAny(listOf("George Orwell", "F. Scott Fitzgerald")) + .alias("byExcludedAuthors") + ) + .execute() + // [END not_eq_any] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#is_nan + fun isNaNFunction() { + // [START is_nan] + // removed + // [END is_nan] + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#is_not_nan + fun isNotNaNFunction() { + // [START is_not_nan] + // removed + // [END is_not_nan] + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#max + fun maxLogicalFunction() { + // [START max_logical_function] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("rating").logicalMaximum(1).alias("flooredRating") + ) + .execute() + // [END max_logical_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/logical_functions#min + fun minLogicalFunction() { + // [START min_logical_function] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("rating").logicalMinimum(5).alias("cappedRating") + ) + .execute() + // [END min_logical_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/map_functions#map_get + fun mapGetFunction() { + // [START map_get] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("awards").mapGet("pulitzer").alias("hasPulitzerAward") + ) + .execute() + // [END map_get] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#byte_length + fun byteLengthFunction() { + // [START byte_length] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("title").byteLength().alias("titleByteLength") + ) + .execute() + // [END byte_length] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#char_length + fun charLengthFunction() { + // [START char_length] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("title").charLength().alias("titleCharLength") + ) + .execute() + // [END char_length] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#starts_with + fun startsWithFunction() { + // [START starts_with] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("title").startsWith("The") + .alias("needsSpecialAlphabeticalSort") + ) + .execute() + // [END starts_with] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#ends_with + fun endsWithFunction() { + // [START ends_with] + val result = db.pipeline() + .collection("inventory/devices/laptops") + .select( + Expression.field("name").endsWith("16 inch") + .alias("16InLaptops") + ) + .execute() + // [END ends_with] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#like + fun likeFunction() { + // [START like] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("genre").like("%Fiction") + .alias("anyFiction") + ) + .execute() + // [END like] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#regex_contains + fun regexContainsFunction() { + // [START regex_contains] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("title").regexContains("Firestore (Enterprise|Standard)") + .alias("isFirestoreRelated") + ) + .execute() + // [END regex_contains] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#regex_match + fun regexMatchFunction() { + // [START regex_match] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("title").regexMatch("Firestore (Enterprise|Standard)") + .alias("isFirestoreExactly") + ) + .execute() + // [END regex_match] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_concat + fun strConcatFunction() { + // [START str_concat] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("title").concat(" by ", Expression.field("author")) + .alias("fullyQualifiedTitle") + ) + .execute() + // [END str_concat] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_contains + fun strContainsFunction() { + // [START string_contains] + val result = db.pipeline() + .collection("articles") + .select( + Expression.field("body").stringContains("Firestore") + .alias("isFirestoreRelated") + ) + .execute() + // [END string_contains] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#to_upper + fun toUpperFunction() { + // [START to_upper] + val result = db.pipeline() + .collection("authors") + .select( + Expression.field("name").toUpper() + .alias("uppercaseName") + ) + .execute() + // [END to_upper] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#to_lower + fun toLowerFunction() { + // [START to_lower] + val result = db.pipeline() + .collection("authors") + .select( + Expression.field("genre").toLower().equal("fantasy") + .alias("isFantasy") + ) + .execute() + // [END to_lower] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#substr + fun substrFunction() { + // [START substr_function] + val result = db.pipeline() + .collection("books") + .where(Expression.field("title").startsWith("The ")) + .select( + Expression.field("title") + .substring(Expression.constant(4), + Expression.field("title").charLength().subtract(4)) + .alias("titleWithoutLeadingThe") + ) + .execute() + // [END substr_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_reverse + fun strReverseFunction() { + // [START str_reverse] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("name").reverse().alias("reversedName") + ) + .execute() + // [END str_reverse] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_trim + fun strTrimFunction() { + // [START trim_function] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("name").trim().alias("whitespaceTrimmedName") + ) + .execute() + // [END trim_function] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_replace + fun strReplaceFunction() { + // not yet supported until GA + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/string_functions#str_split + fun strSplitFunction() { + // not yet supported until GA + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#unix_micros_to_timestamp + fun unixMicrosToTimestampFunction() { + // [START unix_micros_timestamp] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("createdAtMicros").unixMicrosToTimestamp().alias("createdAtString") + ) + .execute() + // [END unix_micros_timestamp] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#unix_millis_to_timestamp + fun unixMillisToTimestampFunction() { + // [START unix_millis_timestamp] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("createdAtMillis").unixMillisToTimestamp().alias("createdAtString") + ) + .execute() + // [END unix_millis_timestamp] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#unix_seconds_to_timestamp + fun unixSecondsToTimestampFunction() { + // [START unix_seconds_timestamp] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("createdAtSeconds").unixSecondsToTimestamp().alias("createdAtString") + ) + .execute() + // [END unix_seconds_timestamp] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_add + fun timestampAddFunction() { + // [START timestamp_add] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("createdAt") + .timestampAdd("day", 3653) + .alias("expiresAt") + ) + .execute() + // [END timestamp_add] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_sub + fun timestampSubFunction() { + // [START timestamp_sub] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("expiresAt") + .timestampSubtract("day", 14) + .alias("sendWarningTimestamp") + ) + .execute() + // [END timestamp_sub] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_to_unix_micros + fun timestampToUnixMicrosFunction() { + // [START timestamp_unix_micros] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("dateString").timestampToUnixMicros().alias("unixMicros") + ) + .execute() + // [END timestamp_unix_micros] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_to_unix_millis + fun timestampToUnixMillisFunction() { + // [START timestamp_unix_millis] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("dateString").timestampToUnixMillis().alias("unixMillis") + ) + .execute() + // [END timestamp_unix_millis] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/timestamp_functions#timestamp_to_unix_seconds + fun timestampToUnixSecondsFunction() { + // [START timestamp_unix_seconds] + val result = db.pipeline() + .collection("documents") + .select( + Expression.field("dateString").timestampToUnixSeconds().alias("unixSeconds") + ) + .execute() + // [END timestamp_unix_seconds] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/vector_functions#cosine_distance + fun cosineDistanceFunction() { + // [START cosine_distance] + val sampleVector = doubleArrayOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0) + val result = db.pipeline() + .collection("books") + .select( + Expression.field("embedding").cosineDistance(sampleVector).alias("cosineDistance") + ) + .execute() + // [END cosine_distance] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/vector_functions#dot_product + fun dotProductFunction() { + // [START dot_product] + val sampleVector = doubleArrayOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0) + val result = db.pipeline() + .collection("books") + .select( + Expression.field("embedding").dotProduct(sampleVector).alias("dotProduct") + ) + .execute() + // [END dot_product] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/vector_functions#euclidean_distance + fun euclideanDistanceFunction() { + // [START euclidean_distance] + val sampleVector = doubleArrayOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0) + val result = db.pipeline() + .collection("books") + .select( + Expression.field("embedding").euclideanDistance(sampleVector).alias("euclideanDistance") + ) + .execute() + // [END euclidean_distance] + println(result) + } + + // https://cloud.google.com/firestore/docs/pipeline/functions/vector_functions#vector_length + fun vectorLengthFunction() { + // [START vector_length] + val result = db.pipeline() + .collection("books") + .select( + Expression.field("embedding").vectorLength().alias("vectorLength") + ) + .execute() + // [END vector_length] + println(result) + } } From 95d5b667b75848776500a86a7d0c7767da405fdd Mon Sep 17 00:00:00 2001 From: Morgan Chen Date: Tue, 4 Nov 2025 15:13:22 -0800 Subject: [PATCH 3/4] add basic read snippet --- .../google/example/firestore/DocSnippets.java | 24 +++++++++++++++++++ .../example/firestore/kotlin/DocSnippets.kt | 18 ++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java b/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java index a0ad4336..f87a7350 100644 --- a/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java +++ b/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java @@ -55,6 +55,7 @@ import java.util.concurrent.TimeUnit; import com.google.firebase.firestore.GeoPoint; import com.google.firebase.firestore.Pipeline; +import com.google.firebase.firestore.PipelineResult; import com.google.firebase.firestore.PipelineSource; import com.google.firebase.firestore.VectorValue; import com.google.firebase.firestore.pipeline.AggregateFunction; @@ -1586,6 +1587,29 @@ void pipelineConcepts() { System.out.println(pipeline); } + void basicPipelineRead() { + // [START basic_pipeline_read] + Pipeline readDataPipeline = db.pipeline() + .collection("users"); + + readDataPipeline.execute() + .addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(Pipeline.Snapshot snapshot) { + for (PipelineResult result : snapshot.getResults()) { + System.out.println(result.getId() + " => " + result.getData()); + } + } + }) + .addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + System.out.println("Error getting documents: " + e); + } + }); + // [END basic_pipeline_read] + } + // https://cloud.google.com/firestore/docs/pipeline/overview#initialization void pipelineInitialization() { // [START pipeline_initialization] diff --git a/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt b/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt index 9e38e7f8..56351dd3 100644 --- a/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt +++ b/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt @@ -1343,6 +1343,24 @@ abstract class DocSnippets(val db: FirebaseFirestore) { println(pipeline) } + fun basicPipelineRead() { + // [START basic_pipeline_read] + val readDataPipeline = db.pipeline() + .collection("users") + + // Execute the pipeline and handle the result + readDataPipeline.execute() + .addOnSuccessListener { result -> + for (document in result) { + println("${document.getId()} => ${document.getData()}") + } + } + .addOnFailureListener { exception -> + println("Error getting documents: $exception") + } + // [END basic_pipeline_read] + } + // https://cloud.google.com/firestore/docs/pipeline/overview#initialization fun pipelineInitialization() { // [START pipeline_initialization] From 6c0a4fc2d670f0af86cb827ccda7c8c79a5a0f96 Mon Sep 17 00:00:00 2001 From: Morgan Chen Date: Thu, 6 Nov 2025 14:47:26 -0800 Subject: [PATCH 4/4] address code review feedback --- .../google/example/firestore/DocSnippets.java | 232 +++++++++--------- .../example/firestore/kotlin/DocSnippets.kt | 230 ++++++++--------- 2 files changed, 233 insertions(+), 229 deletions(-) diff --git a/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java b/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java index f87a7350..4f5b2a51 100644 --- a/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java +++ b/firestore/app/src/main/java/com/google/example/firestore/DocSnippets.java @@ -57,13 +57,15 @@ import com.google.firebase.firestore.Pipeline; import com.google.firebase.firestore.PipelineResult; import com.google.firebase.firestore.PipelineSource; -import com.google.firebase.firestore.VectorValue; import com.google.firebase.firestore.pipeline.AggregateFunction; import com.google.firebase.firestore.pipeline.AggregateStage; import com.google.firebase.firestore.pipeline.Expression; import com.google.firebase.firestore.pipeline.SampleStage; import com.google.firebase.firestore.pipeline.UnnestOptions; +import static com.google.firebase.firestore.pipeline.Expression.field; +import static com.google.firebase.firestore.pipeline.Expression.constant; + /** * Snippets for inclusion in documentation. */ @@ -1577,9 +1579,9 @@ void pipelineConcepts() { // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection - .where(Expression.field("population").greaterThan(100000)) + .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents - .sort(Expression.field("name").ascending()) + .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10); @@ -1624,7 +1626,7 @@ void fieldVsConstants() { // [START field_or_constant] Pipeline pipeline = db.pipeline() .collection("cities") - .where(Expression.field("name").equal(Expression.constant("Toronto"))); + .where(field("name").equal(constant("Toronto"))); // [END field_or_constant] System.out.println(pipeline); } @@ -1659,14 +1661,14 @@ void wherePipeline() { Task results; results = db.pipeline().collection("books") - .where(Expression.field("rating").equal(5)) - .where(Expression.field("published").lessThan(1900)) + .where(field("rating").equal(5)) + .where(field("published").lessThan(1900)) .execute(); results = db.pipeline().collection("books") .where(Expression.and( - Expression.field("rating").equal(5), - Expression.field("published").lessThan(1900) + field("rating").equal(5), + field("published").lessThan(1900) )) .execute(); // [END pipeline_where] @@ -1681,7 +1683,7 @@ void aggregateGroups() { .aggregate(AggregateStage .withAccumulators( AggregateFunction.average("rating").alias("avg_rating")) - .withGroups(Expression.field("genre"))) + .withGroups(field("genre"))) .execute(); // [END aggregate_groups] System.out.println(results); @@ -1693,8 +1695,8 @@ void aggregateDistinct() { Task results = db.pipeline() .collection("books") .distinct( - Expression.field("author").toUpper().alias("author"), - Expression.field("genre") + field("author").toUpper().alias("author"), + field("genre") ) .execute(); // [END aggregate_distinct] @@ -1707,8 +1709,8 @@ void sort() { Task results = db.pipeline() .collection("books") .sort( - Expression.field("release_date").descending(), - Expression.field("author").ascending() + field("release_date").descending(), + field("author").ascending() ) .execute(); // [END sort] @@ -1725,8 +1727,8 @@ void sortComparison() { Pipeline pipeline = db.pipeline() .collection("books") .sort( - Expression.field("release_date").descending(), - Expression.field("author").ascending() + field("release_date").descending(), + field("author").ascending() ); // [END sort_comparison] System.out.println(query); @@ -1742,7 +1744,7 @@ void functions() { // Example: Return the min store price for each book. results = db.pipeline().collection("books") .select( - Expression.field("current").logicalMinimum("updated").alias("price_min") + field("current").logicalMinimum("updated").alias("price_min") ) .execute(); @@ -1760,10 +1762,10 @@ void creatingIndexes() { // [START query_example] Task results = db.pipeline() .collection("books") - .where(Expression.field("published").lessThan(1900)) - .where(Expression.field("genre").equal("Science Fiction")) - .where(Expression.field("rating").greaterThan(4.3)) - .sort(Expression.field("published").descending()) + .where(field("published").lessThan(1900)) + .where(field("genre").equal("Science Fiction")) + .where(field("rating").greaterThan(4.3)) + .sort(field("published").descending()) .execute(); // [END query_example] System.out.println(results); @@ -1774,7 +1776,7 @@ void sparseIndexes() { // [START sparse_index_example] Task results = db.pipeline() .collection("books") - .where(Expression.field("category").like("%fantasy%")) + .where(field("category").like("%fantasy%")) .execute(); // [END sparse_index_example] System.out.println(results); @@ -1784,7 +1786,7 @@ void sparseIndexes2() { // [START sparse_index_example_2] Task results = db.pipeline() .collection("books") - .sort(Expression.field("release_date").ascending()) + .sort(field("release_date").ascending()) .execute(); // [END sparse_index_example_2] System.out.println(results); @@ -1795,10 +1797,10 @@ void coveredQuery() { // [START covered_query] Task results = db.pipeline() .collection("books") - .where(Expression.field("category").like("%fantasy%")) - .where(Expression.field("title").exists()) - .where(Expression.field("author").exists()) - .select(Expression.field("title"), Expression.field("author")) + .where(field("category").like("%fantasy%")) + .where(field("title").exists()) + .where(field("author").exists()) + .select(field("title"), field("author")) .execute(); // [END covered_query] System.out.println(results); @@ -1813,8 +1815,8 @@ void pagination() { // Private preview workaround using pipelines Pipeline pipeline = db.pipeline() .collection("cities") - .where(Expression.field("population").greaterThanOrEqual(1000000)) - .sort(Expression.field("population").descending()); + .where(field("population").greaterThanOrEqual(1000000)) + .sort(field("population").descending()); // [END pagination_not_supported_preview] System.out.println(query); System.out.println(pipeline); @@ -1825,7 +1827,7 @@ void collectionStage() { // [START collection_example] Task results = db.pipeline() .collection("users/bob/games") - .sort(Expression.field("name").ascending()) + .sort(field("name").ascending()) .execute(); // [END collection_example] System.out.println(results); @@ -1836,7 +1838,7 @@ void collectionGroupStage() { // [START collection_group_example] Task results = db.pipeline() .collectionGroup("games") - .sort(Expression.field("name").ascending()) + .sort(field("name").ascending()) .execute(); // [END collection_group_example] System.out.println(results); @@ -1952,12 +1954,12 @@ void unionStage() { // [START union_stage] Task results = db.pipeline() .collection("cities/SF/restaurants") - .where(Expression.field("type").equal("Chinese")) + .where(field("type").equal("Chinese")) .union(db.pipeline() .collection("cities/NY/restaurants") - .where(Expression.field("type").equal("Italian"))) - .where(Expression.field("rating").greaterThanOrEqual(4.5)) - .sort(Expression.field("__name__").descending()) + .where(field("type").equal("Italian"))) + .where(field("rating").greaterThanOrEqual(4.5)) + .sort(field("__name__").descending()) .execute(); // [END union_stage] System.out.println(results); @@ -1968,12 +1970,12 @@ void unionStageStable() { // [START union_stage_stable] Task results = db.pipeline() .collection("cities/SF/restaurants") - .where(Expression.field("type").equal("Chinese")) + .where(field("type").equal("Chinese")) .union(db.pipeline() .collection("cities/NY/restaurants") - .where(Expression.field("type").equal("Italian"))) - .where(Expression.field("rating").greaterThanOrEqual(4.5)) - .sort(Expression.field("__name__").descending()) + .where(field("type").equal("Italian"))) + .where(field("rating").greaterThanOrEqual(4.5)) + .sort(field("__name__").descending()) .execute(); // [END union_stage_stable] System.out.println(results); @@ -1984,7 +1986,7 @@ void unnestStage() { // [START unnest_stage] Task results = db.pipeline() .database() - .unnest(Expression.field("arrayField").alias("unnestedArrayField"), new UnnestOptions().withIndexField("index")) + .unnest(field("arrayField").alias("unnestedArrayField"), new UnnestOptions().withIndexField("index")) .execute(); // [END unnest_stage] System.out.println(results); @@ -2000,7 +2002,7 @@ void unnestStageEmptyOrNonArray() { Task results = db.pipeline() .database() - .unnest(Expression.field("neighbors").alias("unnestedNeighbors"), new UnnestOptions().withIndexField("index")) + .unnest(field("neighbors").alias("unnestedNeighbors"), new UnnestOptions().withIndexField("index")) .execute(); // Output @@ -2036,7 +2038,7 @@ void countIfFunction() { Task result = db.pipeline() .collection("books") .aggregate( - AggregateFunction.countIf(Expression.field("rating").greaterThan(4)).alias("filteredCount") + AggregateFunction.countIf(field("rating").greaterThan(4)).alias("filteredCount") ) .execute(); // [END count_if] @@ -2103,7 +2105,7 @@ void addFunction() { // [START add_function] Task result = db.pipeline() .collection("books") - .select(Expression.add(Expression.field("soldBooks"), Expression.field("unsoldBooks")).alias("totalBooks")) + .select(Expression.add(field("soldBooks"), field("unsoldBooks")).alias("totalBooks")) .execute(); // [END add_function] System.out.println(result); @@ -2115,7 +2117,7 @@ void subtractFunction() { int storeCredit = 7; Task result = db.pipeline() .collection("books") - .select(Expression.subtract(Expression.field("price"), storeCredit).alias("totalCost")) + .select(Expression.subtract(field("price"), storeCredit).alias("totalCost")) .execute(); // [END subtract_function] System.out.println(result); @@ -2126,7 +2128,7 @@ void multiplyFunction() { // [START multiply_function] Task result = db.pipeline() .collection("books") - .select(Expression.multiply(Expression.field("price"), Expression.field("soldBooks")).alias("revenue")) + .select(Expression.multiply(field("price"), field("soldBooks")).alias("revenue")) .execute(); // [END multiply_function] System.out.println(result); @@ -2137,7 +2139,7 @@ void divideFunction() { // [START divide_function] Task result = db.pipeline() .collection("books") - .select(Expression.divide(Expression.field("ratings"), Expression.field("soldBooks")).alias("reviewRate")) + .select(Expression.divide(field("ratings"), field("soldBooks")).alias("reviewRate")) .execute(); // [END divide_function] System.out.println(result); @@ -2149,7 +2151,7 @@ void modFunction() { int displayCapacity = 1000; Task result = db.pipeline() .collection("books") - .select(Expression.mod(Expression.field("unsoldBooks"), displayCapacity).alias("warehousedBooks")) + .select(Expression.mod(field("unsoldBooks"), displayCapacity).alias("warehousedBooks")) .execute(); // [END mod_function] System.out.println(result); @@ -2162,7 +2164,7 @@ void ceilFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.divide(Expression.field("unsoldBooks"), booksPerShelf).ceil().alias("requiredShelves") + Expression.divide(field("unsoldBooks"), booksPerShelf).ceil().alias("requiredShelves") ) .execute(); // [END ceil_function] @@ -2175,7 +2177,7 @@ void floorFunction() { Task result = db.pipeline() .collection("books") .addFields( - Expression.divide(Expression.field("wordCount"), Expression.field("pages")).floor().alias("wordsPerPage") + Expression.divide(field("wordCount"), field("pages")).floor().alias("wordsPerPage") ) .execute(); // [END floor_function] @@ -2187,7 +2189,7 @@ void roundFunction() { // [START round_function] Task result = db.pipeline() .collection("books") - .select(Expression.multiply(Expression.field("soldBooks"), Expression.field("price")).round().alias("partialRevenue")) + .select(Expression.multiply(field("soldBooks"), field("price")).round().alias("partialRevenue")) .aggregate(AggregateFunction.sum("partialRevenue").alias("totalRevenue")) .execute(); // [END round_function] @@ -2201,17 +2203,17 @@ void powFunction() { Task result = db.pipeline() .collection("cities") .addFields( - Expression.field("lat").subtract(googleplex.getLatitude()) + field("lat").subtract(googleplex.getLatitude()) .multiply(111 /* km per degree */) .pow(2) .alias("latitudeDifference"), - Expression.field("lng").subtract(googleplex.getLongitude()) + field("lng").subtract(googleplex.getLongitude()) .multiply(111 /* km per degree */) .pow(2) .alias("longitudeDifference") ) .select( - Expression.field("latitudeDifference").add(Expression.field("longitudeDifference")).sqrt() + field("latitudeDifference").add(field("longitudeDifference")).sqrt() // Inaccurate for large distances or close to poles .alias("approximateDistanceToGoogle") ) @@ -2227,17 +2229,17 @@ void sqrtFunction() { Task result = db.pipeline() .collection("cities") .addFields( - Expression.field("lat").subtract(googleplex.getLatitude()) + field("lat").subtract(googleplex.getLatitude()) .multiply(111 /* km per degree */) .pow(2) .alias("latitudeDifference"), - Expression.field("lng").subtract(googleplex.getLongitude()) + field("lng").subtract(googleplex.getLongitude()) .multiply(111 /* km per degree */) .pow(2) .alias("longitudeDifference") ) .select( - Expression.field("latitudeDifference").add(Expression.field("longitudeDifference")).sqrt() + field("latitudeDifference").add(field("longitudeDifference")).sqrt() // Inaccurate for large distances or close to poles .alias("approximateDistanceToGoogle") ) @@ -2251,7 +2253,7 @@ void expFunction() { // [START exp_function] Task result = db.pipeline() .collection("books") - .select(Expression.field("rating").exp().alias("expRating")) + .select(field("rating").exp().alias("expRating")) .execute(); // [END exp_function] System.out.println(result); @@ -2262,7 +2264,7 @@ void lnFunction() { // [START ln_function] Task result = db.pipeline() .collection("books") - .select(Expression.field("rating").ln().alias("lnRating")) + .select(field("rating").ln().alias("lnRating")) .execute(); // [END ln_function] System.out.println(result); @@ -2280,7 +2282,7 @@ void arrayConcat() { // [START array_concat] Task result = db.pipeline() .collection("books") - .select(Expression.field("genre").arrayConcat(Expression.field("subGenre")).alias("allGenres")) + .select(field("genre").arrayConcat(field("subGenre")).alias("allGenres")) .execute(); // [END array_concat] System.out.println(result); @@ -2291,7 +2293,7 @@ void arrayContains() { // [START array_contains] Task result = db.pipeline() .collection("books") - .select(Expression.field("genre").arrayContains("mystery").alias("isMystery")) + .select(field("genre").arrayContains("mystery").alias("isMystery")) .execute(); // [END array_contains] System.out.println(result); @@ -2303,7 +2305,7 @@ void arrayContainsAll() { Task result = db.pipeline() .collection("books") .select( - Expression.field("genre") + field("genre") .arrayContainsAll(Arrays.asList("fantasy", "adventure")) .alias("isFantasyAdventure") ) @@ -2318,7 +2320,7 @@ void arrayContainsAny() { Task result = db.pipeline() .collection("books") .select( - Expression.field("genre") + field("genre") .arrayContainsAny(Arrays.asList("fantasy", "nonfiction")) .alias("isMysteryOrFantasy") ) @@ -2332,7 +2334,7 @@ void arrayLength() { // [START array_length] Task result = db.pipeline() .collection("books") - .select(Expression.field("genre").arrayLength().alias("genreCount")) + .select(field("genre").arrayLength().alias("genreCount")) .execute(); // [END array_length] System.out.println(result); @@ -2343,7 +2345,7 @@ void arrayReverse() { // [START array_reverse] Task result = db.pipeline() .collection("books") - .select(Expression.field("genre").arrayReverse().alias("reversedGenres")) + .select(field("genre").arrayReverse().alias("reversedGenres")) .execute(); // [END array_reverse] System.out.println(result); @@ -2354,7 +2356,7 @@ void equalFunction() { // [START equal_function] Task result = db.pipeline() .collection("books") - .select(Expression.field("rating").equal(5).alias("hasPerfectRating")) + .select(field("rating").equal(5).alias("hasPerfectRating")) .execute(); // [END equal_function] System.out.println(result); @@ -2365,7 +2367,7 @@ void greaterThanFunction() { // [START greater_than] Task result = db.pipeline() .collection("books") - .select(Expression.field("rating").greaterThan(4).alias("hasHighRating")) + .select(field("rating").greaterThan(4).alias("hasHighRating")) .execute(); // [END greater_than] System.out.println(result); @@ -2376,7 +2378,7 @@ void greaterThanOrEqualToFunction() { // [START greater_or_equal] Task result = db.pipeline() .collection("books") - .select(Expression.field("published").greaterThanOrEqual(1900).alias("publishedIn20thCentury")) + .select(field("published").greaterThanOrEqual(1900).alias("publishedIn20thCentury")) .execute(); // [END greater_or_equal] System.out.println(result); @@ -2387,7 +2389,7 @@ void lessThanFunction() { // [START less_than] Task result = db.pipeline() .collection("books") - .select(Expression.field("published").lessThan(1923).alias("isPublicDomainProbably")) + .select(field("published").lessThan(1923).alias("isPublicDomainProbably")) .execute(); // [END less_than] System.out.println(result); @@ -2398,7 +2400,7 @@ void lessThanOrEqualToFunction() { // [START less_or_equal] Task result = db.pipeline() .collection("books") - .select(Expression.field("rating").lessThanOrEqual(2).alias("hasBadRating")) + .select(field("rating").lessThanOrEqual(2).alias("hasBadRating")) .execute(); // [END less_or_equal] System.out.println(result); @@ -2409,7 +2411,7 @@ void notEqualFunction() { // [START not_equal] Task result = db.pipeline() .collection("books") - .select(Expression.field("title").notEqual("1984").alias("not1984")) + .select(field("title").notEqual("1984").alias("not1984")) .execute(); // [END not_equal] System.out.println(result); @@ -2420,7 +2422,7 @@ void existsFunction() { // [START exists_function] Task result = db.pipeline() .collection("books") - .select(Expression.field("rating").exists().alias("hasRating")) + .select(field("rating").exists().alias("hasRating")) .execute(); // [END exists_function] System.out.println(result); @@ -2433,8 +2435,8 @@ void andFunction() { .collection("books") .select( Expression.and( - Expression.field("rating").greaterThan(4), - Expression.field("price").lessThan(10) + field("rating").greaterThan(4), + field("price").lessThan(10) ).alias("under10Recommendation") ) .execute(); @@ -2449,8 +2451,8 @@ void orFunction() { .collection("books") .select( Expression.or( - Expression.field("genre").equal("Fantasy"), - Expression.field("tags").arrayContains("adventure") + field("genre").equal("Fantasy"), + field("tags").arrayContains("adventure") ).alias("matchesSearchFilters") ) .execute(); @@ -2465,8 +2467,8 @@ void xorFunction() { .collection("books") .select( Expression.xor( - Expression.field("tags").arrayContains("magic"), - Expression.field("tags").arrayContains("nonfiction") + field("tags").arrayContains("magic"), + field("tags").arrayContains("nonfiction") ).alias("matchesSearchFilters") ) .execute(); @@ -2481,7 +2483,7 @@ void notFunction() { .collection("books") .select( Expression.not( - Expression.field("tags").arrayContains("nonfiction") + field("tags").arrayContains("nonfiction") ).alias("isFiction") ) .execute(); @@ -2495,11 +2497,11 @@ void condFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("tags").arrayConcat( + field("tags").arrayConcat( Expression.conditional( - Expression.field("pages").greaterThan(100), - Expression.constant("longRead"), - Expression.constant("shortRead") + field("pages").greaterThan(100), + constant("longRead"), + constant("shortRead") ) ).alias("extendedTags") ) @@ -2514,7 +2516,7 @@ void equalAnyFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("genre").equalAny(Arrays.asList("Science Fiction", "Psychological Thriller")) + field("genre").equalAny(Arrays.asList("Science Fiction", "Psychological Thriller")) .alias("matchesGenreFilters") ) .execute(); @@ -2528,7 +2530,7 @@ void notEqualAnyFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("author").notEqualAny(Arrays.asList("George Orwell", "F. Scott Fitzgerald")) + field("author").notEqualAny(Arrays.asList("George Orwell", "F. Scott Fitzgerald")) .alias("byExcludedAuthors") ) .execute(); @@ -2556,7 +2558,7 @@ void maxLogicalFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("rating").logicalMaximum(1).alias("flooredRating") + field("rating").logicalMaximum(1).alias("flooredRating") ) .execute(); // [END max_logical_function] @@ -2569,7 +2571,7 @@ void minLogicalFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("rating").logicalMinimum(5).alias("cappedRating") + field("rating").logicalMinimum(5).alias("cappedRating") ) .execute(); // [END min_logical_function] @@ -2582,7 +2584,7 @@ void mapGetFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("awards").mapGet("pulitzer").alias("hasPulitzerAward") + field("awards").mapGet("pulitzer").alias("hasPulitzerAward") ) .execute(); // [END map_get] @@ -2595,7 +2597,7 @@ void byteLengthFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("title").byteLength().alias("titleByteLength") + field("title").byteLength().alias("titleByteLength") ) .execute(); // [END byte_length] @@ -2608,7 +2610,7 @@ void charLengthFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("title").charLength().alias("titleCharLength") + field("title").charLength().alias("titleCharLength") ) .execute(); // [END char_length] @@ -2621,7 +2623,7 @@ void startsWithFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("title").startsWith("The") + field("title").startsWith("The") .alias("needsSpecialAlphabeticalSort") ) .execute(); @@ -2635,7 +2637,7 @@ void endsWithFunction() { Task result = db.pipeline() .collection("inventory/devices/laptops") .select( - Expression.field("name").endsWith("16 inch") + field("name").endsWith("16 inch") .alias("16InLaptops") ) .execute(); @@ -2649,7 +2651,7 @@ void likeFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("genre").like("%Fiction") + field("genre").like("%Fiction") .alias("anyFiction") ) .execute(); @@ -2663,7 +2665,7 @@ void regexContainsFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("title").regexContains("Firestore (Enterprise|Standard)") + field("title").regexContains("Firestore (Enterprise|Standard)") .alias("isFirestoreRelated") ) .execute(); @@ -2677,7 +2679,7 @@ void regexMatchFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("title").regexMatch("Firestore (Enterprise|Standard)") + field("title").regexMatch("Firestore (Enterprise|Standard)") .alias("isFirestoreExactly") ) .execute(); @@ -2691,7 +2693,7 @@ void strConcatFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("title").concat(" by ", Expression.field("author")) + field("title").concat(" by ", field("author")) .alias("fullyQualifiedTitle") ) .execute(); @@ -2705,7 +2707,7 @@ void strContainsFunction() { Task result = db.pipeline() .collection("articles") .select( - Expression.field("body").stringContains("Firestore") + field("body").stringContains("Firestore") .alias("isFirestoreRelated") ) .execute(); @@ -2719,7 +2721,7 @@ void toUpperFunction() { Task result = db.pipeline() .collection("authors") .select( - Expression.field("name").toUpper() + field("name").toUpper() .alias("uppercaseName") ) .execute(); @@ -2733,7 +2735,7 @@ void toLowerFunction() { Task result = db.pipeline() .collection("authors") .select( - Expression.field("genre").toLower().equal("fantasy") + field("genre").toLower().equal("fantasy") .alias("isFantasy") ) .execute(); @@ -2746,11 +2748,11 @@ void substrFunction() { // [START substr_function] Task result = db.pipeline() .collection("books") - .where(Expression.field("title").startsWith("The ")) + .where(field("title").startsWith("The ")) .select( - Expression.field("title").substring( - Expression.constant(4), - Expression.field("title").charLength().subtract(4)) + field("title").substring( + constant(4), + field("title").charLength().subtract(4)) .alias("titleWithoutLeadingThe") ) .execute(); @@ -2764,7 +2766,7 @@ void strReverseFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("name").reverse().alias("reversedName") + field("name").reverse().alias("reversedName") ) .execute(); // [END str_reverse] @@ -2777,7 +2779,7 @@ void strTrimFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("name").trim().alias("whitespaceTrimmedName") + field("name").trim().alias("whitespaceTrimmedName") ) .execute(); // [END trim_function] @@ -2800,7 +2802,7 @@ void unixMicrosToTimestampFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("createdAtMicros").unixMicrosToTimestamp().alias("createdAtString") + field("createdAtMicros").unixMicrosToTimestamp().alias("createdAtString") ) .execute(); // [END unix_micros_timestamp] @@ -2813,7 +2815,7 @@ void unixMillisToTimestampFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("createdAtMillis").unixMillisToTimestamp().alias("createdAtString") + field("createdAtMillis").unixMillisToTimestamp().alias("createdAtString") ) .execute(); // [END unix_millis_timestamp] @@ -2826,7 +2828,7 @@ void unixSecondsToTimestampFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("createdAtSeconds").unixSecondsToTimestamp().alias("createdAtString") + field("createdAtSeconds").unixSecondsToTimestamp().alias("createdAtString") ) .execute(); // [END unix_seconds_timestamp] @@ -2839,7 +2841,7 @@ void timestampAddFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("createdAt").timestampAdd("day", 3653).alias("expiresAt") + field("createdAt").timestampAdd("day", 3653).alias("expiresAt") ) .execute(); // [END timestamp_add] @@ -2852,7 +2854,7 @@ void timestampSubFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("expiresAt").timestampSubtract("day", 14).alias("sendWarningTimestamp") + field("expiresAt").timestampSubtract("day", 14).alias("sendWarningTimestamp") ) .execute(); // [END timestamp_sub] @@ -2865,7 +2867,7 @@ void timestampToUnixMicrosFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("dateString").timestampToUnixMicros().alias("unixMicros") + field("dateString").timestampToUnixMicros().alias("unixMicros") ) .execute(); // [END timestamp_unix_micros] @@ -2878,7 +2880,7 @@ void timestampToUnixMillisFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("dateString").timestampToUnixMillis().alias("unixMillis") + field("dateString").timestampToUnixMillis().alias("unixMillis") ) .execute(); // [END timestamp_unix_millis] @@ -2891,7 +2893,7 @@ void timestampToUnixSecondsFunction() { Task result = db.pipeline() .collection("documents") .select( - Expression.field("dateString").timestampToUnixSeconds().alias("unixSeconds") + field("dateString").timestampToUnixSeconds().alias("unixSeconds") ) .execute(); // [END timestamp_unix_seconds] @@ -2905,7 +2907,7 @@ void cosineDistanceFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("embedding").cosineDistance(sampleVector).alias("cosineDistance") + field("embedding").cosineDistance(sampleVector).alias("cosineDistance") ) .execute(); // [END cosine_distance] @@ -2919,7 +2921,7 @@ void dotProductFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("embedding").dotProduct(sampleVector).alias("dotProduct") + field("embedding").dotProduct(sampleVector).alias("dotProduct") ) .execute(); // [END dot_product] @@ -2933,7 +2935,7 @@ void euclideanDistanceFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("embedding").euclideanDistance(sampleVector).alias("euclideanDistance") + field("embedding").euclideanDistance(sampleVector).alias("euclideanDistance") ) .execute(); // [END euclidean_distance] @@ -2946,7 +2948,7 @@ void vectorLengthFunction() { Task result = db.pipeline() .collection("books") .select( - Expression.field("embedding").vectorLength().alias("vectorLength") + field("embedding").vectorLength().alias("vectorLength") ) .execute(); // [END vector_length] diff --git a/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt b/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt index 56351dd3..deadd086 100644 --- a/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt +++ b/firestore/app/src/main/java/com/google/example/firestore/kotlin/DocSnippets.kt @@ -34,6 +34,8 @@ import com.google.firebase.firestore.Pipeline import com.google.firebase.firestore.pipeline.AggregateFunction import com.google.firebase.firestore.pipeline.AggregateStage import com.google.firebase.firestore.pipeline.Expression +import com.google.firebase.firestore.pipeline.Expression.Companion.field +import com.google.firebase.firestore.pipeline.Expression.Companion.constant import com.google.firebase.firestore.pipeline.SampleStage import com.google.firebase.firestore.pipeline.UnnestOptions @@ -1333,9 +1335,9 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection - .where(Expression.field("population").greaterThan(100000)) + .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents - .sort(Expression.field("name").ascending()) + .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10) @@ -1375,7 +1377,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START field_or_constant] val pipeline = db.pipeline() .collection("cities") - .where(Expression.field("name").equal(Expression.constant("Toronto"))) + .where(field("name").equal(constant("Toronto"))) // [END field_or_constant] println(pipeline) } @@ -1410,13 +1412,13 @@ abstract class DocSnippets(val db: FirebaseFirestore) { var results: Task results = db.pipeline().collection("books") - .where(Expression.field("rating").equal(5)) - .where(Expression.field("published").lessThan(1900)) + .where(field("rating").equal(5)) + .where(field("published").lessThan(1900)) .execute() results = db.pipeline().collection("books") - .where(Expression.and(Expression.field("rating").equal(5), - Expression.field("published").lessThan(1900))) + .where(Expression.and(field("rating").equal(5), + field("published").lessThan(1900))) .execute() // [END pipeline_where] println(results) @@ -1430,7 +1432,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { .aggregate( AggregateStage .withAccumulators(AggregateFunction.average("rating").alias("avg_rating")) - .withGroups(Expression.field("genre")) + .withGroups(field("genre")) ) .execute() // [END aggregate_groups] @@ -1443,8 +1445,8 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val results = db.pipeline() .collection("books") .distinct( - Expression.field("author").toUpper().alias("author"), - Expression.field("genre") + field("author").toUpper().alias("author"), + field("genre") ) .execute() // [END aggregate_distinct] @@ -1457,8 +1459,8 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val results = db.pipeline() .collection("books") .sort( - Expression.field("release_date").descending(), - Expression.field("author").ascending() + field("release_date").descending(), + field("author").ascending() ) .execute() // [END sort] @@ -1475,8 +1477,8 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val pipeline = db.pipeline() .collection("books") .sort( - Expression.field("release_date").descending(), - Expression.field("author").ascending() + field("release_date").descending(), + field("author").ascending() ) // [END sort_comparison] println(query) @@ -1492,7 +1494,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // Example: Return the min store price for each book. results = db.pipeline().collection("books") .select( - Expression.field("current").logicalMinimum("updated").alias("price_min") + field("current").logicalMinimum("updated").alias("price_min") ) .execute() @@ -1510,10 +1512,10 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START query_example] val results = db.pipeline() .collection("books") - .where(Expression.field("published").lessThan(1900)) - .where(Expression.field("genre").equal("Science Fiction")) - .where(Expression.field("rating").greaterThan(4.3)) - .sort(Expression.field("published").descending()) + .where(field("published").lessThan(1900)) + .where(field("genre").equal("Science Fiction")) + .where(field("rating").greaterThan(4.3)) + .sort(field("published").descending()) .execute() // [END query_example] println(results) @@ -1524,7 +1526,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START sparse_index_example] val results = db.pipeline() .collection("books") - .where(Expression.field("category").like("%fantasy%")) + .where(field("category").like("%fantasy%")) .execute() // [END sparse_index_example] println(results) @@ -1534,7 +1536,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START sparse_index_example_2] val results = db.pipeline() .collection("books") - .sort(Expression.field("release_date").ascending()) + .sort(field("release_date").ascending()) .execute() // [END sparse_index_example_2] println(results) @@ -1545,10 +1547,10 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START covered_query] val results = db.pipeline() .collection("books") - .where(Expression.field("category").like("%fantasy%")) - .where(Expression.field("title").exists()) - .where(Expression.field("author").exists()) - .select(Expression.field("title"), Expression.field("author")) + .where(field("category").like("%fantasy%")) + .where(field("title").exists()) + .where(field("author").exists()) + .select(field("title"), field("author")) .execute() // [END covered_query] println(results) @@ -1563,8 +1565,8 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // Private preview workaround using pipelines val pipeline = db.pipeline() .collection("cities") - .where(Expression.field("population").greaterThanOrEqual(1000000)) - .sort(Expression.field("population").descending()) + .where(field("population").greaterThanOrEqual(1000000)) + .sort(field("population").descending()) // [END pagination_not_supported_preview] println(query) println(pipeline) @@ -1575,7 +1577,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START collection_example] val results = db.pipeline() .collection("users/bob/games") - .sort(Expression.field("name").ascending()) + .sort(field("name").ascending()) .execute() // [END collection_example] println(results) @@ -1586,7 +1588,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START collection_group_example] val results = db.pipeline() .collectionGroup("games") - .sort(Expression.field("name").ascending()) + .sort(field("name").ascending()) .execute() // [END collection_group_example] println(results) @@ -1702,12 +1704,12 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START union_stage] val results = db.pipeline() .collection("cities/SF/restaurants") - .where(Expression.field("type").equal("Chinese")) + .where(field("type").equal("Chinese")) .union(db.pipeline() .collection("cities/NY/restaurants") - .where(Expression.field("type").equal("Italian"))) - .where(Expression.field("rating").greaterThanOrEqual(4.5)) - .sort(Expression.field("__name__").descending()) + .where(field("type").equal("Italian"))) + .where(field("rating").greaterThanOrEqual(4.5)) + .sort(field("__name__").descending()) .execute() // [END union_stage] println(results) @@ -1718,12 +1720,12 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START union_stage_stable] val results = db.pipeline() .collection("cities/SF/restaurants") - .where(Expression.field("type").equal("Chinese")) + .where(field("type").equal("Chinese")) .union(db.pipeline() .collection("cities/NY/restaurants") - .where(Expression.field("type").equal("Italian"))) - .where(Expression.field("rating").greaterThanOrEqual(4.5)) - .sort(Expression.field("__name__").descending()) + .where(field("type").equal("Italian"))) + .where(field("rating").greaterThanOrEqual(4.5)) + .sort(field("__name__").descending()) .execute() // [END union_stage_stable] println(results) @@ -1734,7 +1736,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START unnest_stage] val results = db.pipeline() .database() - .unnest(Expression.field("arrayField").alias("unnestedArrayField"), UnnestOptions().withIndexField("index")) + .unnest(field("arrayField").alias("unnestedArrayField"), UnnestOptions().withIndexField("index")) .execute() // [END unnest_stage] println(results) @@ -1750,7 +1752,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val results = db.pipeline() .database() - .unnest(Expression.field("neighbors").alias("unnestedNeighbors"), UnnestOptions().withIndexField("index")) + .unnest(field("neighbors").alias("unnestedNeighbors"), UnnestOptions().withIndexField("index")) .execute() // Output @@ -1786,7 +1788,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .aggregate( - AggregateFunction.countIf(Expression.field("rating").greaterThan(4)).alias("filteredCount") + AggregateFunction.countIf(field("rating").greaterThan(4)).alias("filteredCount") ) .execute() // [END count_if] @@ -1853,7 +1855,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START add_function] val result = db.pipeline() .collection("books") - .select(Expression.add(Expression.field("soldBooks"), Expression.field("unsoldBooks")).alias("totalBooks")) + .select(Expression.add(field("soldBooks"), field("unsoldBooks")).alias("totalBooks")) .execute() // [END add_function] println(result) @@ -1865,7 +1867,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val storeCredit = 7 val result = db.pipeline() .collection("books") - .select(Expression.subtract(Expression.field("price"), storeCredit).alias("totalCost")) + .select(Expression.subtract(field("price"), storeCredit).alias("totalCost")) .execute() // [END subtract_function] println(result) @@ -1876,7 +1878,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START multiply_function] val result = db.pipeline() .collection("books") - .select(Expression.multiply(Expression.field("price"), Expression.field("soldBooks")).alias("revenue")) + .select(Expression.multiply(field("price"), field("soldBooks")).alias("revenue")) .execute() // [END multiply_function] println(result) @@ -1887,7 +1889,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START divide_function] val result = db.pipeline() .collection("books") - .select(Expression.divide(Expression.field("ratings"), Expression.field("soldBooks")).alias("reviewRate")) + .select(Expression.divide(field("ratings"), field("soldBooks")).alias("reviewRate")) .execute() // [END divide_function] println(result) @@ -1899,7 +1901,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val displayCapacity = 1000 val result = db.pipeline() .collection("books") - .select(Expression.mod(Expression.field("unsoldBooks"), displayCapacity).alias("warehousedBooks")) + .select(Expression.mod(field("unsoldBooks"), displayCapacity).alias("warehousedBooks")) .execute() // [END mod_function] println(result) @@ -1912,7 +1914,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.divide(Expression.field("unsoldBooks"), booksPerShelf).ceil().alias("requiredShelves") + Expression.divide(field("unsoldBooks"), booksPerShelf).ceil().alias("requiredShelves") ) .execute() // [END ceil_function] @@ -1925,7 +1927,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .addFields( - Expression.divide(Expression.field("wordCount"), Expression.field("pages")).floor().alias("wordsPerPage") + Expression.divide(field("wordCount"), field("pages")).floor().alias("wordsPerPage") ) .execute() // [END floor_function] @@ -1937,7 +1939,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START round_function] val result = db.pipeline() .collection("books") - .select(Expression.multiply(Expression.field("soldBooks"), Expression.field("price")).round().alias("partialRevenue")) + .select(Expression.multiply(field("soldBooks"), field("price")).round().alias("partialRevenue")) .aggregate(AggregateFunction.sum("partialRevenue").alias("totalRevenue")) .execute() // [END round_function] @@ -1951,17 +1953,17 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("cities") .addFields( - Expression.field("lat").subtract(googleplex.latitude) + field("lat").subtract(googleplex.latitude) .multiply(111 /* km per degree */) .pow(2) .alias("latitudeDifference"), - Expression.field("lng").subtract(googleplex.longitude) + field("lng").subtract(googleplex.longitude) .multiply(111 /* km per degree */) .pow(2) .alias("longitudeDifference") ) .select( - Expression.field("latitudeDifference").add(Expression.field("longitudeDifference")).sqrt() + field("latitudeDifference").add(field("longitudeDifference")).sqrt() // Inaccurate for large distances or close to poles .alias("approximateDistanceToGoogle") ) @@ -1977,17 +1979,17 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("cities") .addFields( - Expression.field("lat").subtract(googleplex.latitude) + field("lat").subtract(googleplex.latitude) .multiply(111 /* km per degree */) .pow(2) .alias("latitudeDifference"), - Expression.field("lng").subtract(googleplex.longitude) + field("lng").subtract(googleplex.longitude) .multiply(111 /* km per degree */) .pow(2) .alias("longitudeDifference") ) .select( - Expression.field("latitudeDifference").add(Expression.field("longitudeDifference")).sqrt() + field("latitudeDifference").add(field("longitudeDifference")).sqrt() // Inaccurate for large distances or close to poles .alias("approximateDistanceToGoogle") ) @@ -2001,7 +2003,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START exp_function] val result = db.pipeline() .collection("books") - .select(Expression.field("rating").exp().alias("expRating")) + .select(field("rating").exp().alias("expRating")) .execute() // [END exp_function] println(result) @@ -2012,7 +2014,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START ln_function] val result = db.pipeline() .collection("books") - .select(Expression.field("rating").ln().alias("lnRating")) + .select(field("rating").ln().alias("lnRating")) .execute() // [END ln_function] println(result) @@ -2030,7 +2032,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START array_concat] val result = db.pipeline() .collection("books") - .select(Expression.field("genre").arrayConcat(Expression.field("subGenre")).alias("allGenres")) + .select(field("genre").arrayConcat(field("subGenre")).alias("allGenres")) .execute() // [END array_concat] println(result) @@ -2041,7 +2043,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START array_contains] val result = db.pipeline() .collection("books") - .select(Expression.field("genre").arrayContains("mystery").alias("isMystery")) + .select(field("genre").arrayContains("mystery").alias("isMystery")) .execute() // [END array_contains] println(result) @@ -2053,7 +2055,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("genre") + field("genre") .arrayContainsAll(listOf("fantasy", "adventure")) .alias("isFantasyAdventure") ) @@ -2068,7 +2070,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("genre") + field("genre") .arrayContainsAny(listOf("fantasy", "nonfiction")) .alias("isMysteryOrFantasy") ) @@ -2082,7 +2084,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START array_length] val result = db.pipeline() .collection("books") - .select(Expression.field("genre").arrayLength().alias("genreCount")) + .select(field("genre").arrayLength().alias("genreCount")) .execute() // [END array_length] println(result) @@ -2093,7 +2095,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START array_reverse] val result = db.pipeline() .collection("books") - .select(Expression.field("genre").arrayReverse().alias("reversedGenres")) + .select(field("genre").arrayReverse().alias("reversedGenres")) .execute() // [END array_reverse] println(result) @@ -2104,7 +2106,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START equal_function] val result = db.pipeline() .collection("books") - .select(Expression.field("rating").equal(5).alias("hasPerfectRating")) + .select(field("rating").equal(5).alias("hasPerfectRating")) .execute() // [END equal_function] println(result) @@ -2115,7 +2117,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START greater_than] val result = db.pipeline() .collection("books") - .select(Expression.field("rating").greaterThan(4).alias("hasHighRating")) + .select(field("rating").greaterThan(4).alias("hasHighRating")) .execute() // [END greater_than] println(result) @@ -2126,7 +2128,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START greater_or_equal] val result = db.pipeline() .collection("books") - .select(Expression.field("published").greaterThanOrEqual(1900).alias("publishedIn20thCentury")) + .select(field("published").greaterThanOrEqual(1900).alias("publishedIn20thCentury")) .execute() // [END greater_or_equal] println(result) @@ -2137,7 +2139,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START less_than] val result = db.pipeline() .collection("books") - .select(Expression.field("published").lessThan(1923).alias("isPublicDomainProbably")) + .select(field("published").lessThan(1923).alias("isPublicDomainProbably")) .execute() // [END less_than] println(result) @@ -2148,7 +2150,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START less_or_equal] val result = db.pipeline() .collection("books") - .select(Expression.field("rating").lessThanOrEqual(2).alias("hasBadRating")) + .select(field("rating").lessThanOrEqual(2).alias("hasBadRating")) .execute() // [END less_or_equal] println(result) @@ -2159,7 +2161,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START not_equal] val result = db.pipeline() .collection("books") - .select(Expression.field("title").notEqual("1984").alias("not1984")) + .select(field("title").notEqual("1984").alias("not1984")) .execute() // [END not_equal] println(result) @@ -2170,7 +2172,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START exists_function] val result = db.pipeline() .collection("books") - .select(Expression.field("rating").exists().alias("hasRating")) + .select(field("rating").exists().alias("hasRating")) .execute() // [END exists_function] println(result) @@ -2182,8 +2184,8 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.and(Expression.field("rating").greaterThan(4), - Expression.field("price").lessThan(10)) + Expression.and(field("rating").greaterThan(4), + field("price").lessThan(10)) .alias("under10Recommendation") ) .execute() @@ -2197,8 +2199,8 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.or(Expression.field("genre").equal("Fantasy"), - Expression.field("tags").arrayContains("adventure")) + Expression.or(field("genre").equal("Fantasy"), + field("tags").arrayContains("adventure")) .alias("matchesSearchFilters") ) .execute() @@ -2212,8 +2214,8 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.xor(Expression.field("tags").arrayContains("magic"), - Expression.field("tags").arrayContains("nonfiction")) + Expression.xor(field("tags").arrayContains("magic"), + field("tags").arrayContains("nonfiction")) .alias("matchesSearchFilters") ) .execute() @@ -2228,7 +2230,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { .collection("books") .select( Expression.not( - Expression.field("tags").arrayContains("nonfiction") + field("tags").arrayContains("nonfiction") ).alias("isFiction") ) .execute() @@ -2242,11 +2244,11 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("tags").arrayConcat( + field("tags").arrayConcat( Expression.conditional( - Expression.field("pages").greaterThan(100), - Expression.constant("longRead"), - Expression.constant("shortRead") + field("pages").greaterThan(100), + constant("longRead"), + constant("shortRead") ) ).alias("extendedTags") ) @@ -2261,7 +2263,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("genre").equalAny(listOf("Science Fiction", "Psychological Thriller")) + field("genre").equalAny(listOf("Science Fiction", "Psychological Thriller")) .alias("matchesGenreFilters") ) .execute() @@ -2275,7 +2277,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("author").notEqualAny(listOf("George Orwell", "F. Scott Fitzgerald")) + field("author").notEqualAny(listOf("George Orwell", "F. Scott Fitzgerald")) .alias("byExcludedAuthors") ) .execute() @@ -2303,7 +2305,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("rating").logicalMaximum(1).alias("flooredRating") + field("rating").logicalMaximum(1).alias("flooredRating") ) .execute() // [END max_logical_function] @@ -2316,7 +2318,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("rating").logicalMinimum(5).alias("cappedRating") + field("rating").logicalMinimum(5).alias("cappedRating") ) .execute() // [END min_logical_function] @@ -2329,7 +2331,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("awards").mapGet("pulitzer").alias("hasPulitzerAward") + field("awards").mapGet("pulitzer").alias("hasPulitzerAward") ) .execute() // [END map_get] @@ -2342,7 +2344,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("title").byteLength().alias("titleByteLength") + field("title").byteLength().alias("titleByteLength") ) .execute() // [END byte_length] @@ -2355,7 +2357,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("title").charLength().alias("titleCharLength") + field("title").charLength().alias("titleCharLength") ) .execute() // [END char_length] @@ -2368,7 +2370,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("title").startsWith("The") + field("title").startsWith("The") .alias("needsSpecialAlphabeticalSort") ) .execute() @@ -2382,7 +2384,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("inventory/devices/laptops") .select( - Expression.field("name").endsWith("16 inch") + field("name").endsWith("16 inch") .alias("16InLaptops") ) .execute() @@ -2396,7 +2398,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("genre").like("%Fiction") + field("genre").like("%Fiction") .alias("anyFiction") ) .execute() @@ -2410,7 +2412,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("title").regexContains("Firestore (Enterprise|Standard)") + field("title").regexContains("Firestore (Enterprise|Standard)") .alias("isFirestoreRelated") ) .execute() @@ -2424,7 +2426,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("title").regexMatch("Firestore (Enterprise|Standard)") + field("title").regexMatch("Firestore (Enterprise|Standard)") .alias("isFirestoreExactly") ) .execute() @@ -2438,7 +2440,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("title").concat(" by ", Expression.field("author")) + field("title").concat(" by ", field("author")) .alias("fullyQualifiedTitle") ) .execute() @@ -2452,7 +2454,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("articles") .select( - Expression.field("body").stringContains("Firestore") + field("body").stringContains("Firestore") .alias("isFirestoreRelated") ) .execute() @@ -2466,7 +2468,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("authors") .select( - Expression.field("name").toUpper() + field("name").toUpper() .alias("uppercaseName") ) .execute() @@ -2480,7 +2482,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("authors") .select( - Expression.field("genre").toLower().equal("fantasy") + field("genre").toLower().equal("fantasy") .alias("isFantasy") ) .execute() @@ -2493,11 +2495,11 @@ abstract class DocSnippets(val db: FirebaseFirestore) { // [START substr_function] val result = db.pipeline() .collection("books") - .where(Expression.field("title").startsWith("The ")) + .where(field("title").startsWith("The ")) .select( - Expression.field("title") - .substring(Expression.constant(4), - Expression.field("title").charLength().subtract(4)) + field("title") + .substring(constant(4), + field("title").charLength().subtract(4)) .alias("titleWithoutLeadingThe") ) .execute() @@ -2511,7 +2513,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("name").reverse().alias("reversedName") + field("name").reverse().alias("reversedName") ) .execute() // [END str_reverse] @@ -2524,7 +2526,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("name").trim().alias("whitespaceTrimmedName") + field("name").trim().alias("whitespaceTrimmedName") ) .execute() // [END trim_function] @@ -2547,7 +2549,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("createdAtMicros").unixMicrosToTimestamp().alias("createdAtString") + field("createdAtMicros").unixMicrosToTimestamp().alias("createdAtString") ) .execute() // [END unix_micros_timestamp] @@ -2560,7 +2562,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("createdAtMillis").unixMillisToTimestamp().alias("createdAtString") + field("createdAtMillis").unixMillisToTimestamp().alias("createdAtString") ) .execute() // [END unix_millis_timestamp] @@ -2573,7 +2575,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("createdAtSeconds").unixSecondsToTimestamp().alias("createdAtString") + field("createdAtSeconds").unixSecondsToTimestamp().alias("createdAtString") ) .execute() // [END unix_seconds_timestamp] @@ -2586,7 +2588,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("createdAt") + field("createdAt") .timestampAdd("day", 3653) .alias("expiresAt") ) @@ -2601,7 +2603,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("expiresAt") + field("expiresAt") .timestampSubtract("day", 14) .alias("sendWarningTimestamp") ) @@ -2616,7 +2618,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("dateString").timestampToUnixMicros().alias("unixMicros") + field("dateString").timestampToUnixMicros().alias("unixMicros") ) .execute() // [END timestamp_unix_micros] @@ -2629,7 +2631,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("dateString").timestampToUnixMillis().alias("unixMillis") + field("dateString").timestampToUnixMillis().alias("unixMillis") ) .execute() // [END timestamp_unix_millis] @@ -2642,7 +2644,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("documents") .select( - Expression.field("dateString").timestampToUnixSeconds().alias("unixSeconds") + field("dateString").timestampToUnixSeconds().alias("unixSeconds") ) .execute() // [END timestamp_unix_seconds] @@ -2656,7 +2658,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("embedding").cosineDistance(sampleVector).alias("cosineDistance") + field("embedding").cosineDistance(sampleVector).alias("cosineDistance") ) .execute() // [END cosine_distance] @@ -2670,7 +2672,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("embedding").dotProduct(sampleVector).alias("dotProduct") + field("embedding").dotProduct(sampleVector).alias("dotProduct") ) .execute() // [END dot_product] @@ -2684,7 +2686,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("embedding").euclideanDistance(sampleVector).alias("euclideanDistance") + field("embedding").euclideanDistance(sampleVector).alias("euclideanDistance") ) .execute() // [END euclidean_distance] @@ -2697,7 +2699,7 @@ abstract class DocSnippets(val db: FirebaseFirestore) { val result = db.pipeline() .collection("books") .select( - Expression.field("embedding").vectorLength().alias("vectorLength") + field("embedding").vectorLength().alias("vectorLength") ) .execute() // [END vector_length]