From 91a80d3e7e338059dd62271766fcfd2ee21934f3 Mon Sep 17 00:00:00 2001 From: Yvonne Pan <103622026+yvonnep165@users.noreply.github.com> Date: Tue, 24 Feb 2026 10:41:41 -0500 Subject: [PATCH 1/7] feat: add first, last, arrayAgg and arrayAggDistinct expressions --- api-report/firestore.api.md | 32 +++++ dev/src/pipelines/expression.ts | 230 ++++++++++++++++++++++++++++++++ dev/src/pipelines/index.ts | 4 + dev/system-test/pipeline.ts | 49 +++++++ types/firestore.d.ts | 194 +++++++++++++++++++++++++++ 5 files changed, 509 insertions(+) diff --git a/api-report/firestore.api.md b/api-report/firestore.api.md index c31af8697..4ba555ec6 100644 --- a/api-report/firestore.api.md +++ b/api-report/firestore.api.md @@ -169,6 +169,18 @@ function and(first: BooleanExpression, second: BooleanExpression, ...more: Boole // @beta function array(elements: unknown[]): FunctionExpression; +// @beta +function arrayAgg(expression: Expression): AggregateFunction; + +// @beta +function arrayAgg(fieldName: string): AggregateFunction; + +// @beta +function arrayAggDistinct(expression: Expression): AggregateFunction; + +// @beta +function arrayAggDistinct(fieldName: string): AggregateFunction; + // @beta function arrayConcat(firstArray: Expression, secondArray: Expression | unknown[], ...otherArrays: Array): FunctionExpression; @@ -958,6 +970,8 @@ export class ExplainResults implements firestore.ExplainResults { abstract class Expression implements firestore.Pipelines.Expression, HasUserData { abs(): FunctionExpression; add(second: firestore.Pipelines.Expression | unknown, ...others: Array): FunctionExpression; + arrayAgg(): AggregateFunction; + arrayAggDistinct(): AggregateFunction; arrayConcat(secondArray: Expression | unknown[], ...otherArrays: Array): FunctionExpression; arrayContains(expression: Expression): BooleanExpression; arrayContains(value: unknown): BooleanExpression; @@ -1003,6 +1017,7 @@ abstract class Expression implements firestore.Pipelines.Expression, HasUserData exp(): FunctionExpression; // (undocumented) abstract expressionType: firestore.Pipelines.ExpressionType; + first(): AggregateFunction; floor(): FunctionExpression; greaterThan(expression: Expression): BooleanExpression; greaterThan(value: unknown): BooleanExpression; @@ -1016,6 +1031,7 @@ abstract class Expression implements firestore.Pipelines.Expression, HasUserData isError(): BooleanExpression; join(delimiterExpression: Expression): Expression; join(delimiter: string): Expression; + last(): AggregateFunction; length(): FunctionExpression; lessThan(experession: Expression): BooleanExpression; lessThan(value: unknown): BooleanExpression; @@ -1397,6 +1413,12 @@ class Firestore implements firestore.Firestore { export { Firestore } export default Firestore; +// @beta +function first(expression: Expression): AggregateFunction; + +// @beta +function first(fieldName: string): AggregateFunction; + // @beta function floor(expr: Expression): FunctionExpression; @@ -1517,6 +1539,12 @@ function join(arrayExpression: Expression, delimiter: string): Expression; // @beta function join(arrayFieldName: string, delimiterExpression: Expression): Expression; +// @beta +function last(expression: Expression): AggregateFunction; + +// @beta +function last(fieldName: string): AggregateFunction; + // @beta function length_2(fieldName: string): FunctionExpression; @@ -1894,6 +1922,10 @@ declare namespace Pipelines { Constant, sum, maximum, + first, + last, + arrayAgg, + arrayAggDistinct, descending, greaterThanOrEqual, multiply, diff --git a/dev/src/pipelines/expression.ts b/dev/src/pipelines/expression.ts index 5b335ab47..1b1582e30 100644 --- a/dev/src/pipelines/expression.ts +++ b/dev/src/pipelines/expression.ts @@ -1451,6 +1451,80 @@ export abstract class Expression return new AggregateFunction('maximum', [this]); } + /** + * @beta + * Creates an aggregation that finds the first value of an expression across multiple stage inputs. + * + * @example + * ```typescript + * // Find the first value of the 'rating' field + * field("rating").first().as("firstRating"); + * ``` + * + * @returns A new `AggregateFunction` representing the 'first' aggregation. + */ + first(): AggregateFunction { + return new AggregateFunction('first', [this]); + } + + /** + * @beta + * Creates an aggregation that finds the last value of an expression across multiple stage inputs. + * + * @example + * ```typescript + * // Find the last value of the 'rating' field + * field("rating").last().as("lastRating"); + * ``` + * + * @returns A new `AggregateFunction` representing the 'last' aggregation. + */ + last(): AggregateFunction { + return new AggregateFunction('last', [this]); + } + + /** + * @beta + * Creates an aggregation that collects all values of an expression across multiple stage inputs + * into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all tags from books into an array + * field("tags").arrayAgg().as("allTags"); + * ``` + * + * @returns A new `AggregateFunction` representing the 'array_agg' aggregation. + */ + arrayAgg(): AggregateFunction { + return new AggregateFunction('array_agg', [this]); + } + + /** + * @beta + * Creates an aggregation that collects all distinct values of an expression across multiple stage + * inputs into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all distinct tags from books into an array + * field("tags").arrayAggDistinct().as("allDistinctTags"); + * ``` + * + * @returns A new `AggregateFunction` representing the 'array_agg_distinct' aggregation. + */ + arrayAggDistinct(): AggregateFunction { + return new AggregateFunction('array_agg_distinct', [this]); + } + /** * @beta * Creates an aggregation that counts the number of distinct values of the expression or field. @@ -6807,6 +6881,162 @@ export function maximum(value: Expression | string): AggregateFunction { return fieldOrExpression(value).maximum(); } +/** + * @beta + * Creates an aggregation that finds the first value of an expression across multiple stage + * inputs. + * + * @example + * ```typescript + * // Find the first value of the 'rating' field + * first(field("rating")).as("firstRating"); + * ``` + * + * @param expression - The expression to find the first value of. + * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'first' aggregation. + */ +export function first(expression: Expression): AggregateFunction; + +/** + * @beta + * Creates an aggregation that finds the first value of a field across multiple stage inputs. + * + * @example + * ```typescript + * // Find the first value of the 'rating' field + * first("rating").as("firstRating"); + * ``` + * + * @param fieldName - The name of the field to find the first value of. + * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'first' aggregation. + */ +export function first(fieldName: string): AggregateFunction; +export function first(value: Expression | string): AggregateFunction { + return fieldOrExpression(value).first(); +} + +/** + * @beta + * Creates an aggregation that finds the last value of an expression across multiple stage + * inputs. + * + * @example + * ```typescript + * // Find the last value of the 'rating' field + * last(field("rating")).as("lastRating"); + * ``` + * + * @param expression - The expression to find the last value of. + * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'last' aggregation. + */ +export function last(expression: Expression): AggregateFunction; + +/** + * @beta + * Creates an aggregation that finds the last value of a field across multiple stage inputs. + * + * @example + * ```typescript + * // Find the last value of the 'rating' field + * last("rating").as("lastRating"); + * ``` + * + * @param fieldName - The name of the field to find the last value of. + * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'last' aggregation. + */ +export function last(fieldName: string): AggregateFunction; +export function last(value: Expression | string): AggregateFunction { + return fieldOrExpression(value).last(); +} + +/** + * @beta + * Creates an aggregation that collects all values of an expression across multiple stage + * inputs into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all tags from books into an array + * arrayAgg(field("tags")).as("allTags"); + * ``` + * + * @param expression - The expression to collect values from. + * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg' aggregation. + */ +export function arrayAgg(expression: Expression): AggregateFunction; + +/** + * @beta + * Creates an aggregation that collects all values of a field across multiple stage inputs + * into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all tags from books into an array + * arrayAgg("tags").as("allTags"); + * ``` + * + * @param fieldName - The name of the field to collect values from. + * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg' aggregation. + */ +export function arrayAgg(fieldName: string): AggregateFunction; +export function arrayAgg(value: Expression | string): AggregateFunction { + return fieldOrExpression(value).arrayAgg(); +} + +/** + * @beta + * Creates an aggregation that collects all distinct values of an expression across multiple stage + * inputs into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all distinct tags from books into an array + * arrayAggDistinct(field("tags")).as("allDistinctTags"); + * ``` + * + * @param expression - The expression to collect values from. + * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg_distinct' aggregation. + */ +export function arrayAggDistinct(expression: Expression): AggregateFunction; + +/** + * @beta + * Creates an aggregation that collects all distinct values of a field across multiple stage inputs + * into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all distinct tags from books into an array + * arrayAggDistinct("tags").as("allDistinctTags"); + * ``` + * + * @param fieldName - The name of the field to collect values from. + * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg_distinct' aggregation. + */ +export function arrayAggDistinct(fieldName: string): AggregateFunction; +export function arrayAggDistinct( + value: Expression | string +): AggregateFunction { + return fieldOrExpression(value).arrayAggDistinct(); +} + /** * @beta * Calculates the Cosine distance between a field's vector value and a literal vector value. diff --git a/dev/src/pipelines/index.ts b/dev/src/pipelines/index.ts index a73c661fe..eb4f45750 100644 --- a/dev/src/pipelines/index.ts +++ b/dev/src/pipelines/index.ts @@ -87,6 +87,10 @@ export { Constant, sum, maximum, + first, + last, + arrayAgg, + arrayAggDistinct, descending, greaterThanOrEqual, multiply, diff --git a/dev/system-test/pipeline.ts b/dev/system-test/pipeline.ts index 9a2901e11..2ef03a867 100644 --- a/dev/system-test/pipeline.ts +++ b/dev/system-test/pipeline.ts @@ -38,6 +38,10 @@ import { multiply, sum, maximum, + first, + last, + arrayAgg, + arrayAggDistinct, descending, FunctionExpression, minimum, @@ -1035,6 +1039,51 @@ describe.skipClassic('Pipeline class', () => { }); }); + it.only('returns first and last accumulations', async () => { + const snapshot = await firestore + .pipeline() + .collection(randomCol.path) + .sort(field('published').ascending()) + .aggregate( + first('rating').as('firstBookRating'), + first('title').as('firstBookTitle'), + last('rating').as('lastBookRating'), + last('title').as('lastBookTitle') + ) + .execute(); + expectResults(snapshot, { + firstBookRating: 4.5, + firstBookTitle: 'Pride and Prejudice', + lastBookRating: 4.1, + lastBookTitle: "The Handmaid's Tale" + }); + }); + + it.only('returns arrayAgg accumulations', async () => { + const snapshot = await firestore + .pipeline() + .collection(randomCol.path) + .sort(field('published').ascending()) + .aggregate(arrayAgg('rating').as('allRatings')) + .execute(); + expectResults(snapshot, { + allRatings: [4.5, 4.3, 4.0, 4.2, 4.7, 4.2, 4.6, 4.3, 4.2, 4.1] + }); + }); + + it.only('returns arrayAggDistinct accumulations', async () => { + const snapshot = await firestore + .pipeline() + .collection(randomCol.path) + .aggregate(arrayAggDistinct('rating').as('allDistinctRatings')) + .execute(); + const data = snapshot.results[0].data(); + data['allDistinctRatings'].sort((a: number, b: number) => a - b); + expect(data).to.deep.equal({ + allDistinctRatings: [4.0, 4.1, 4.2, 4.3, 4.5, 4.6, 4.7] + }); + }); + it('rejects groups without accumulators', async () => { void expect(async () => { await firestore diff --git a/types/firestore.d.ts b/types/firestore.d.ts index d0df93c16..044e2ebac 100644 --- a/types/firestore.d.ts +++ b/types/firestore.d.ts @@ -4276,6 +4276,68 @@ declare namespace FirebaseFirestore { * @returns A new `AggregateFunction` representing the 'max' aggregation. */ maximum(): AggregateFunction; + /** + * @beta + * Creates an aggregation that finds the first value of an expression across multiple stage inputs. + * + * @example + * ```typescript + * // Find the first value of the 'rating' field + * field("rating").first().as("firstRating"); + * ``` + * + * @returns A new `AggregateFunction` representing the 'first' aggregation. + */ + first(): AggregateFunction; + /** + * @beta + * Creates an aggregation that finds the last value of an expression across multiple stage inputs. + * + * @example + * ```typescript + * // Find the last value of the 'rating' field + * field("rating").last().as("lastRating"); + * ``` + * + * @returns A new `AggregateFunction` representing the 'last' aggregation. + */ + last(): AggregateFunction; + /** + * @beta + * Creates an aggregation that collects all values of an expression across multiple stage inputs + * into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all tags from books into an array + * field("tags").arrayAgg().as("allTags"); + * ``` + * + * @returns A new `AggregateFunction` representing the 'array_agg' aggregation. + */ + arrayAgg(): AggregateFunction; + /** + * @beta + * Creates an aggregation that collects all distinct values of an expression across multiple stage + * inputs into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all distinct tags from books into an array + * field("tags").arrayAggDistinct().as("allDistinctTags"); + * ``` + * + * @returns A new `AggregateFunction` representing the 'array_agg_distinct' aggregation. + */ + arrayAggDistinct(): AggregateFunction; /** * @beta * Creates an expression that returns the larger value between this expression and another expression, based on Firestore's value type ordering. @@ -8773,6 +8835,138 @@ declare namespace FirebaseFirestore { * @returns A new {@code AggregateFunction} representing the 'max' aggregation. */ export function maximum(fieldName: string): AggregateFunction; + /** + * @beta + * Creates an aggregation that finds the first value of an expression across multiple stage + * inputs. + * + * @example + * ```typescript + * // Find the first value of the 'rating' field + * first(field("rating")).as("firstRating"); + * ``` + * + * @param expression The expression to find the first value of. + * @returns A new {@code AggregateFunction} representing the 'first' aggregation. + */ + export function first(expression: Expression): AggregateFunction; + /** + * @beta + * Creates an aggregation that finds the first value of a field across multiple stage inputs. + * + * @example + * ```typescript + * // Find the first value of the 'rating' field + * first("rating").as("firstRating"); + * ``` + * + * @param fieldName The name of the field to find the first value of. + * @returns A new {@code AggregateFunction} representing the 'first' aggregation. + */ + export function first(fieldName: string): AggregateFunction; + /** + * @beta + * Creates an aggregation that finds the last value of an expression across multiple stage + * inputs. + * + * @example + * ```typescript + * // Find the last value of the 'rating' field + * last(field("rating")).as("lastRating"); + * ``` + * + * @param expression The expression to find the last value of. + * @returns A new {@code AggregateFunction} representing the 'last' aggregation. + */ + export function last(expression: Expression): AggregateFunction; + /** + * @beta + * Creates an aggregation that finds the last value of a field across multiple stage inputs. + * + * @example + * ```typescript + * // Find the last value of the 'rating' field + * last("rating").as("lastRating"); + * ``` + * + * @param fieldName The name of the field to find the last value of. + * @returns A new {@code AggregateFunction} representing the 'last' aggregation. + */ + export function last(fieldName: string): AggregateFunction; + /** + * @beta + * Creates an aggregation that collects all values of an expression across multiple stage + * inputs into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all tags from books into an array + * arrayAgg(field("tags")).as("allTags"); + * ``` + * + * @param expression The expression to collect values from. + * @returns A new {@code AggregateFunction} representing the 'array_agg' aggregation. + */ + export function arrayAgg(expression: Expression): AggregateFunction; + /** + * @beta + * Creates an aggregation that collects all values of a field across multiple stage inputs + * into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all tags from books into an array + * arrayAgg("tags").as("allTags"); + * ``` + * + * @param fieldName The name of the field to collect values from. + * @returns A new {@code AggregateFunction} representing the 'array_agg' aggregation. + */ + export function arrayAgg(fieldName: string): AggregateFunction; + /** + * @beta + * Creates an aggregation that collects all distinct values of an expression across multiple stage + * inputs into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all distinct tags from books into an array + * arrayAggDistinct(field("tags")).as("allDistinctTags"); + * ``` + * @param expression The expression to collect values from. + * @returns A new {@code AggregateFunction} representing the 'array_agg_distinct' aggregation. + */ + export function arrayAggDistinct(expression: Expression): AggregateFunction; + /** + * @beta + * Creates an aggregation that collects all distinct values of a field across multiple stage inputs + * into an array. + * + * @remarks + * If the expression resolves to an absent value, it is converted to `null`. + * The order of elements in the output array is not stable and shouldn't be relied upon. + * + * @example + * ```typescript + * // Collect all distinct tags from books into an array + * arrayAggDistinct("tags").as("allDistinctTags"); + * ``` + * @param fieldName The name of the field to collect values from. + * @returns A new {@code AggregateFunction} representing the 'array_agg_distinct' aggregation. + */ + export function arrayAggDistinct(fieldName: string): AggregateFunction; /** * @beta * Calculates the Cosine distance between a field's vector value and a literal vector value. From 236af3ae5f88a9f3fe55b2df49c5fa67f758985c Mon Sep 17 00:00:00 2001 From: Yvonne Pan <103622026+yvonnep165@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:02:43 -0500 Subject: [PATCH 2/7] remove the only error for tests --- dev/system-test/pipeline.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/system-test/pipeline.ts b/dev/system-test/pipeline.ts index 2ef03a867..542bc45aa 100644 --- a/dev/system-test/pipeline.ts +++ b/dev/system-test/pipeline.ts @@ -1039,7 +1039,7 @@ describe.skipClassic('Pipeline class', () => { }); }); - it.only('returns first and last accumulations', async () => { + it('returns first and last accumulations', async () => { const snapshot = await firestore .pipeline() .collection(randomCol.path) @@ -1059,7 +1059,7 @@ describe.skipClassic('Pipeline class', () => { }); }); - it.only('returns arrayAgg accumulations', async () => { + it('returns arrayAgg accumulations', async () => { const snapshot = await firestore .pipeline() .collection(randomCol.path) @@ -1071,7 +1071,7 @@ describe.skipClassic('Pipeline class', () => { }); }); - it.only('returns arrayAggDistinct accumulations', async () => { + it('returns arrayAggDistinct accumulations', async () => { const snapshot = await firestore .pipeline() .collection(randomCol.path) From 027b4db63d1cbab271b50508e5d7721bf592c5b7 Mon Sep 17 00:00:00 2001 From: Yvonne Pan <103622026+yvonnep165@users.noreply.github.com> Date: Wed, 25 Feb 2026 10:49:47 -0500 Subject: [PATCH 3/7] remove the dash for doc consistency --- dev/src/pipelines/expression.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dev/src/pipelines/expression.ts b/dev/src/pipelines/expression.ts index 1b1582e30..f77e51a87 100644 --- a/dev/src/pipelines/expression.ts +++ b/dev/src/pipelines/expression.ts @@ -6892,7 +6892,7 @@ export function maximum(value: Expression | string): AggregateFunction { * first(field("rating")).as("firstRating"); * ``` * - * @param expression - The expression to find the first value of. + * @param expression The expression to find the first value of. * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'first' aggregation. */ export function first(expression: Expression): AggregateFunction; @@ -6907,7 +6907,7 @@ export function first(expression: Expression): AggregateFunction; * first("rating").as("firstRating"); * ``` * - * @param fieldName - The name of the field to find the first value of. + * @param fieldName The name of the field to find the first value of. * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'first' aggregation. */ export function first(fieldName: string): AggregateFunction; @@ -6926,7 +6926,7 @@ export function first(value: Expression | string): AggregateFunction { * last(field("rating")).as("lastRating"); * ``` * - * @param expression - The expression to find the last value of. + * @param expression The expression to find the last value of. * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'last' aggregation. */ export function last(expression: Expression): AggregateFunction; @@ -6941,7 +6941,7 @@ export function last(expression: Expression): AggregateFunction; * last("rating").as("lastRating"); * ``` * - * @param fieldName - The name of the field to find the last value of. + * @param fieldName The name of the field to find the last value of. * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'last' aggregation. */ export function last(fieldName: string): AggregateFunction; @@ -6964,7 +6964,7 @@ export function last(value: Expression | string): AggregateFunction { * arrayAgg(field("tags")).as("allTags"); * ``` * - * @param expression - The expression to collect values from. + * @param expression The expression to collect values from. * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg' aggregation. */ export function arrayAgg(expression: Expression): AggregateFunction; @@ -6984,7 +6984,7 @@ export function arrayAgg(expression: Expression): AggregateFunction; * arrayAgg("tags").as("allTags"); * ``` * - * @param fieldName - The name of the field to collect values from. + * @param fieldName The name of the field to collect values from. * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg' aggregation. */ export function arrayAgg(fieldName: string): AggregateFunction; @@ -7007,7 +7007,7 @@ export function arrayAgg(value: Expression | string): AggregateFunction { * arrayAggDistinct(field("tags")).as("allDistinctTags"); * ``` * - * @param expression - The expression to collect values from. + * @param expression The expression to collect values from. * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg_distinct' aggregation. */ export function arrayAggDistinct(expression: Expression): AggregateFunction; @@ -7027,7 +7027,7 @@ export function arrayAggDistinct(expression: Expression): AggregateFunction; * arrayAggDistinct("tags").as("allDistinctTags"); * ``` * - * @param fieldName - The name of the field to collect values from. + * @param fieldName The name of the field to collect values from. * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg_distinct' aggregation. */ export function arrayAggDistinct(fieldName: string): AggregateFunction; From e2b9807745ba26cd1d17d41ed49eb376d3812dfe Mon Sep 17 00:00:00 2001 From: Yvonne Pan <103622026+yvonnep165@users.noreply.github.com> Date: Wed, 25 Feb 2026 11:24:40 -0500 Subject: [PATCH 4/7] replace the the function link with --- dev/src/pipelines/expression.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dev/src/pipelines/expression.ts b/dev/src/pipelines/expression.ts index f77e51a87..c9c820b26 100644 --- a/dev/src/pipelines/expression.ts +++ b/dev/src/pipelines/expression.ts @@ -6893,7 +6893,7 @@ export function maximum(value: Expression | string): AggregateFunction { * ``` * * @param expression The expression to find the first value of. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'first' aggregation. + * @returns A new `AggregateFunction` representing the 'first' aggregation. */ export function first(expression: Expression): AggregateFunction; @@ -6908,7 +6908,7 @@ export function first(expression: Expression): AggregateFunction; * ``` * * @param fieldName The name of the field to find the first value of. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'first' aggregation. + * @returns A new `AggregateFunction` representing the 'first' aggregation. */ export function first(fieldName: string): AggregateFunction; export function first(value: Expression | string): AggregateFunction { @@ -6927,7 +6927,7 @@ export function first(value: Expression | string): AggregateFunction { * ``` * * @param expression The expression to find the last value of. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'last' aggregation. + * @returns A new `AggregateFunction` representing the 'last' aggregation. */ export function last(expression: Expression): AggregateFunction; @@ -6942,7 +6942,7 @@ export function last(expression: Expression): AggregateFunction; * ``` * * @param fieldName The name of the field to find the last value of. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'last' aggregation. + * @returns A new `AggregateFunction` representing the 'last' aggregation. */ export function last(fieldName: string): AggregateFunction; export function last(value: Expression | string): AggregateFunction { @@ -6965,7 +6965,7 @@ export function last(value: Expression | string): AggregateFunction { * ``` * * @param expression The expression to collect values from. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg' aggregation. + * @returns A new `AggregateFunction` representing the 'array_agg' aggregation. */ export function arrayAgg(expression: Expression): AggregateFunction; @@ -6985,7 +6985,7 @@ export function arrayAgg(expression: Expression): AggregateFunction; * ``` * * @param fieldName The name of the field to collect values from. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg' aggregation. + * @returns A new `AggregateFunction` representing the 'array_agg' aggregation. */ export function arrayAgg(fieldName: string): AggregateFunction; export function arrayAgg(value: Expression | string): AggregateFunction { @@ -7008,7 +7008,7 @@ export function arrayAgg(value: Expression | string): AggregateFunction { * ``` * * @param expression The expression to collect values from. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg_distinct' aggregation. + * @returns A new `AggregateFunction` representing the 'array_agg_distinct' aggregation. */ export function arrayAggDistinct(expression: Expression): AggregateFunction; @@ -7028,7 +7028,7 @@ export function arrayAggDistinct(expression: Expression): AggregateFunction; * ``` * * @param fieldName The name of the field to collect values from. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg_distinct' aggregation. + * @returns A new `AggregateFunction` representing the 'array_agg_distinct' aggregation. */ export function arrayAggDistinct(fieldName: string): AggregateFunction; export function arrayAggDistinct( From 7c6247e04f9e82f6323dd577d50b5f12b893bcba Mon Sep 17 00:00:00 2001 From: Yvonne Pan <103622026+yvonnep165@users.noreply.github.com> Date: Wed, 25 Feb 2026 11:24:40 -0500 Subject: [PATCH 5/7] replace the function link with aggregationFunction --- dev/src/pipelines/expression.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dev/src/pipelines/expression.ts b/dev/src/pipelines/expression.ts index f77e51a87..c9c820b26 100644 --- a/dev/src/pipelines/expression.ts +++ b/dev/src/pipelines/expression.ts @@ -6893,7 +6893,7 @@ export function maximum(value: Expression | string): AggregateFunction { * ``` * * @param expression The expression to find the first value of. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'first' aggregation. + * @returns A new `AggregateFunction` representing the 'first' aggregation. */ export function first(expression: Expression): AggregateFunction; @@ -6908,7 +6908,7 @@ export function first(expression: Expression): AggregateFunction; * ``` * * @param fieldName The name of the field to find the first value of. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'first' aggregation. + * @returns A new `AggregateFunction` representing the 'first' aggregation. */ export function first(fieldName: string): AggregateFunction; export function first(value: Expression | string): AggregateFunction { @@ -6927,7 +6927,7 @@ export function first(value: Expression | string): AggregateFunction { * ``` * * @param expression The expression to find the last value of. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'last' aggregation. + * @returns A new `AggregateFunction` representing the 'last' aggregation. */ export function last(expression: Expression): AggregateFunction; @@ -6942,7 +6942,7 @@ export function last(expression: Expression): AggregateFunction; * ``` * * @param fieldName The name of the field to find the last value of. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'last' aggregation. + * @returns A new `AggregateFunction` representing the 'last' aggregation. */ export function last(fieldName: string): AggregateFunction; export function last(value: Expression | string): AggregateFunction { @@ -6965,7 +6965,7 @@ export function last(value: Expression | string): AggregateFunction { * ``` * * @param expression The expression to collect values from. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg' aggregation. + * @returns A new `AggregateFunction` representing the 'array_agg' aggregation. */ export function arrayAgg(expression: Expression): AggregateFunction; @@ -6985,7 +6985,7 @@ export function arrayAgg(expression: Expression): AggregateFunction; * ``` * * @param fieldName The name of the field to collect values from. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg' aggregation. + * @returns A new `AggregateFunction` representing the 'array_agg' aggregation. */ export function arrayAgg(fieldName: string): AggregateFunction; export function arrayAgg(value: Expression | string): AggregateFunction { @@ -7008,7 +7008,7 @@ export function arrayAgg(value: Expression | string): AggregateFunction { * ``` * * @param expression The expression to collect values from. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg_distinct' aggregation. + * @returns A new `AggregateFunction` representing the 'array_agg_distinct' aggregation. */ export function arrayAggDistinct(expression: Expression): AggregateFunction; @@ -7028,7 +7028,7 @@ export function arrayAggDistinct(expression: Expression): AggregateFunction; * ``` * * @param fieldName The name of the field to collect values from. - * @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'array_agg_distinct' aggregation. + * @returns A new `AggregateFunction` representing the 'array_agg_distinct' aggregation. */ export function arrayAggDistinct(fieldName: string): AggregateFunction; export function arrayAggDistinct( From e87c018a0cc53db8a78033b811bd4741f4e6ee62 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Wed, 25 Feb 2026 16:31:19 +0000 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- dev/src/pipelines/expression.ts | 2 +- dev/system-test/pipeline.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dev/src/pipelines/expression.ts b/dev/src/pipelines/expression.ts index c9c820b26..b1d422655 100644 --- a/dev/src/pipelines/expression.ts +++ b/dev/src/pipelines/expression.ts @@ -7032,7 +7032,7 @@ export function arrayAggDistinct(expression: Expression): AggregateFunction; */ export function arrayAggDistinct(fieldName: string): AggregateFunction; export function arrayAggDistinct( - value: Expression | string + value: Expression | string, ): AggregateFunction { return fieldOrExpression(value).arrayAggDistinct(); } diff --git a/dev/system-test/pipeline.ts b/dev/system-test/pipeline.ts index 542bc45aa..52faa4aa2 100644 --- a/dev/system-test/pipeline.ts +++ b/dev/system-test/pipeline.ts @@ -1048,14 +1048,14 @@ describe.skipClassic('Pipeline class', () => { first('rating').as('firstBookRating'), first('title').as('firstBookTitle'), last('rating').as('lastBookRating'), - last('title').as('lastBookTitle') + last('title').as('lastBookTitle'), ) .execute(); expectResults(snapshot, { firstBookRating: 4.5, firstBookTitle: 'Pride and Prejudice', lastBookRating: 4.1, - lastBookTitle: "The Handmaid's Tale" + lastBookTitle: "The Handmaid's Tale", }); }); @@ -1067,7 +1067,7 @@ describe.skipClassic('Pipeline class', () => { .aggregate(arrayAgg('rating').as('allRatings')) .execute(); expectResults(snapshot, { - allRatings: [4.5, 4.3, 4.0, 4.2, 4.7, 4.2, 4.6, 4.3, 4.2, 4.1] + allRatings: [4.5, 4.3, 4.0, 4.2, 4.7, 4.2, 4.6, 4.3, 4.2, 4.1], }); }); @@ -1080,7 +1080,7 @@ describe.skipClassic('Pipeline class', () => { const data = snapshot.results[0].data(); data['allDistinctRatings'].sort((a: number, b: number) => a - b); expect(data).to.deep.equal({ - allDistinctRatings: [4.0, 4.1, 4.2, 4.3, 4.5, 4.6, 4.7] + allDistinctRatings: [4.0, 4.1, 4.2, 4.3, 4.5, 4.6, 4.7], }); }); From 101fb18478727a9f312926fd8c61b400959a75b1 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Wed, 25 Feb 2026 16:36:52 +0000 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- dev/src/pipelines/expression.ts | 2 +- dev/system-test/pipeline.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dev/src/pipelines/expression.ts b/dev/src/pipelines/expression.ts index c9c820b26..b1d422655 100644 --- a/dev/src/pipelines/expression.ts +++ b/dev/src/pipelines/expression.ts @@ -7032,7 +7032,7 @@ export function arrayAggDistinct(expression: Expression): AggregateFunction; */ export function arrayAggDistinct(fieldName: string): AggregateFunction; export function arrayAggDistinct( - value: Expression | string + value: Expression | string, ): AggregateFunction { return fieldOrExpression(value).arrayAggDistinct(); } diff --git a/dev/system-test/pipeline.ts b/dev/system-test/pipeline.ts index 542bc45aa..52faa4aa2 100644 --- a/dev/system-test/pipeline.ts +++ b/dev/system-test/pipeline.ts @@ -1048,14 +1048,14 @@ describe.skipClassic('Pipeline class', () => { first('rating').as('firstBookRating'), first('title').as('firstBookTitle'), last('rating').as('lastBookRating'), - last('title').as('lastBookTitle') + last('title').as('lastBookTitle'), ) .execute(); expectResults(snapshot, { firstBookRating: 4.5, firstBookTitle: 'Pride and Prejudice', lastBookRating: 4.1, - lastBookTitle: "The Handmaid's Tale" + lastBookTitle: "The Handmaid's Tale", }); }); @@ -1067,7 +1067,7 @@ describe.skipClassic('Pipeline class', () => { .aggregate(arrayAgg('rating').as('allRatings')) .execute(); expectResults(snapshot, { - allRatings: [4.5, 4.3, 4.0, 4.2, 4.7, 4.2, 4.6, 4.3, 4.2, 4.1] + allRatings: [4.5, 4.3, 4.0, 4.2, 4.7, 4.2, 4.6, 4.3, 4.2, 4.1], }); }); @@ -1080,7 +1080,7 @@ describe.skipClassic('Pipeline class', () => { const data = snapshot.results[0].data(); data['allDistinctRatings'].sort((a: number, b: number) => a - b); expect(data).to.deep.equal({ - allDistinctRatings: [4.0, 4.1, 4.2, 4.3, 4.5, 4.6, 4.7] + allDistinctRatings: [4.0, 4.1, 4.2, 4.3, 4.5, 4.6, 4.7], }); });