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") 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..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 @@ -53,6 +53,18 @@ 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.PipelineResult; +import com.google.firebase.firestore.PipelineSource; +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. @@ -1559,4 +1571,1387 @@ 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(field("population").greaterThan(100000)) + // Step 3: Sort the remaining documents + .sort(field("name").ascending()) + // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have + // unintentional results. + .limit(10); + // [END pipeline_concepts] + 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] + 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(field("name").equal(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(field("rating").equal(5)) + .where(field("published").lessThan(1900)) + .execute(); + + results = db.pipeline().collection("books") + .where(Expression.and( + field("rating").equal(5), + field("published").lessThan(1900) + )) + .execute(); + // [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(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( + field("author").toUpper().alias("author"), + 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( + field("release_date").descending(), + 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( + field("release_date").descending(), + 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( + 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(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); + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#existing_sparse_indexes + void sparseIndexes() { + // [START sparse_index_example] + Task results = db.pipeline() + .collection("books") + .where(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(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(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); + } + + // 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(field("population").greaterThanOrEqual(1000000)) + .sort(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(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(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(field("type").equal("Chinese")) + .union(db.pipeline() + .collection("cities/NY/restaurants") + .where(field("type").equal("Italian"))) + .where(field("rating").greaterThanOrEqual(4.5)) + .sort(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(field("type").equal("Chinese")) + .union(db.pipeline() + .collection("cities/NY/restaurants") + .where(field("type").equal("Italian"))) + .where(field("rating").greaterThanOrEqual(4.5)) + .sort(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(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(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(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(field("soldBooks"), 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(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(field("price"), 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(field("ratings"), 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(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(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(field("wordCount"), 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(field("soldBooks"), 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( + field("lat").subtract(googleplex.getLatitude()) + .multiply(111 /* km per degree */) + .pow(2) + .alias("latitudeDifference"), + field("lng").subtract(googleplex.getLongitude()) + .multiply(111 /* km per degree */) + .pow(2) + .alias("longitudeDifference") + ) + .select( + field("latitudeDifference").add(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( + field("lat").subtract(googleplex.getLatitude()) + .multiply(111 /* km per degree */) + .pow(2) + .alias("latitudeDifference"), + field("lng").subtract(googleplex.getLongitude()) + .multiply(111 /* km per degree */) + .pow(2) + .alias("longitudeDifference") + ) + .select( + field("latitudeDifference").add(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(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(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(field("genre").arrayConcat(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(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( + 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( + 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(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(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(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(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(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(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(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(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(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( + field("rating").greaterThan(4), + 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( + field("genre").equal("Fantasy"), + 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( + field("tags").arrayContains("magic"), + 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( + 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( + field("tags").arrayConcat( + Expression.conditional( + field("pages").greaterThan(100), + constant("longRead"), + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + field("title").concat(" by ", 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( + 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( + 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( + 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(field("title").startsWith("The ")) + .select( + field("title").substring( + constant(4), + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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..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 @@ -28,6 +28,16 @@ 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.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 /** * Kotlin version of doc snippets. @@ -1317,4 +1327,1382 @@ 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(field("population").greaterThan(100000)) + // Step 3: Sort the remaining documents + .sort(field("name").ascending()) + // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have + // unintentional results. + .limit(10) + // [END pipeline_concepts] + 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] + 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(field("name").equal(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(field("rating").equal(5)) + .where(field("published").lessThan(1900)) + .execute() + + results = db.pipeline().collection("books") + .where(Expression.and(field("rating").equal(5), + field("published").lessThan(1900))) + .execute() + // [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(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( + field("author").toUpper().alias("author"), + 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( + field("release_date").descending(), + 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( + field("release_date").descending(), + 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( + 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(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) + } + + // https://cloud.google.com/firestore/docs/pipeline/overview#existing_sparse_indexes + fun sparseIndexes() { + // [START sparse_index_example] + val results = db.pipeline() + .collection("books") + .where(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(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(field("category").like("%fantasy%")) + .where(field("title").exists()) + .where(field("author").exists()) + .select(field("title"), 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(field("population").greaterThanOrEqual(1000000)) + .sort(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(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(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(field("type").equal("Chinese")) + .union(db.pipeline() + .collection("cities/NY/restaurants") + .where(field("type").equal("Italian"))) + .where(field("rating").greaterThanOrEqual(4.5)) + .sort(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(field("type").equal("Chinese")) + .union(db.pipeline() + .collection("cities/NY/restaurants") + .where(field("type").equal("Italian"))) + .where(field("rating").greaterThanOrEqual(4.5)) + .sort(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(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(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(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(field("soldBooks"), 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(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(field("price"), 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(field("ratings"), 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(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(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(field("wordCount"), 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(field("soldBooks"), 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( + field("lat").subtract(googleplex.latitude) + .multiply(111 /* km per degree */) + .pow(2) + .alias("latitudeDifference"), + field("lng").subtract(googleplex.longitude) + .multiply(111 /* km per degree */) + .pow(2) + .alias("longitudeDifference") + ) + .select( + field("latitudeDifference").add(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( + field("lat").subtract(googleplex.latitude) + .multiply(111 /* km per degree */) + .pow(2) + .alias("latitudeDifference"), + field("lng").subtract(googleplex.longitude) + .multiply(111 /* km per degree */) + .pow(2) + .alias("longitudeDifference") + ) + .select( + field("latitudeDifference").add(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(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(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(field("genre").arrayConcat(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(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( + 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( + 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(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(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(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(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(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(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(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(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(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(field("rating").greaterThan(4), + 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(field("genre").equal("Fantasy"), + 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(field("tags").arrayContains("magic"), + 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( + 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( + field("tags").arrayConcat( + Expression.conditional( + field("pages").greaterThan(100), + constant("longRead"), + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + field("title").concat(" by ", 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( + 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( + 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( + 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(field("title").startsWith("The ")) + .select( + field("title") + .substring(constant(4), + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + 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( + field("embedding").vectorLength().alias("vectorLength") + ) + .execute() + // [END vector_length] + println(result) + } }