@@ -28,6 +28,7 @@ import {
2828} from './pipeline-util' ;
2929import { HasUserData , Serializer , validateUserInput } from '../serializer' ;
3030import { cast } from '../util' ;
31+ import { Pipeline } from './pipelines' ;
3132
3233/**
3334 * Represents an expression that can be evaluated to a value within the execution of a `Pipeline`.
@@ -3072,6 +3073,22 @@ export abstract class Expression
30723073 ] ) . asBoolean ( ) ;
30733074 }
30743075
3076+ /**
3077+ * Creates an expression that returns the value of a field from the document that results from the evaluation of this expression.
3078+ *
3079+ * @example
3080+ * ```typescript
3081+ * // Get the value of the "city" field in the "address" document.
3082+ * field("address").getField("city")
3083+ * ```
3084+ *
3085+ * @param key The field to access in the document.
3086+ * @returns A new `Expression` representing the value of the field in the document.
3087+ */
3088+ getField ( key : string | Expression ) : Expression {
3089+ return new FunctionExpression ( 'get_field' , [ this , valueToDefaultExpr ( key ) ] ) ;
3090+ }
3091+
30753092 // TODO(new-expression): Add new expression method definitions above this line
30763093
30773094 /**
@@ -10238,6 +10255,184 @@ export function isType(
1023810255 return fieldOrExpression ( fieldNameOrExpression ) . isType ( type ) ;
1023910256}
1024010257
10258+ /**
10259+ * Creates an expression that gets a field from this map (object).
10260+ *
10261+ * @example
10262+ * ```typescript
10263+ * // Get the value of the "city" field in the "address" document.
10264+ * getField(field("address"), "city")
10265+ * ```
10266+ *
10267+ * @param expression The expression evaluating to the map from which the field will be extracted.
10268+ * @param key The field to access in the document.
10269+ * @returns A new `Expression` representing the value of the field in the document.
10270+ */
10271+ export function getField ( expression : Expression , key : string ) : Expression ;
10272+ /**
10273+ * Creates an expression that gets a field from this map (object).
10274+ *
10275+ * @example
10276+ * ```typescript
10277+ * // Get the value of the "city" field in the "address" document.
10278+ * getField(field("address"), "city")
10279+ * ```
10280+ *
10281+ * @param expression The expression evaluating to the map from which the field will be extracted.
10282+ * @param keyExpr The expression representing the key to access in the document.
10283+ * @returns A new `Expression` representing the value of the field in the document.
10284+ */
10285+ export function getField (
10286+ expression : Expression ,
10287+ keyExpr : Expression ,
10288+ ) : Expression ;
10289+ /**
10290+ * Creates an expression that returns the value of a field from the document with the given field name.
10291+ *
10292+ * @example
10293+ * ```typescript
10294+ * // Get the value of the "city" field in the "address" document.
10295+ * getField("address", "city")
10296+ * ```
10297+ *
10298+ * @param fieldName The name of the field containing the map/document.
10299+ * @param key The key to access.
10300+ * @returns A new `Expression` representing the value of the field in the document.
10301+ */
10302+ export function getField ( fieldName : string , key : string ) : Expression ;
10303+ /**
10304+ * Creates an expression that returns the value of a field from the document with the given field name.
10305+ *
10306+ * @example
10307+ * ```typescript
10308+ * // Get the value of the "city" field in the "address" document.
10309+ * getField("address", variable("addressField"))
10310+ * ```
10311+ *
10312+ * @param fieldName The name of the field containing the map/document.
10313+ * @param keyExpr The key expression to access.
10314+ * @returns A new `Expression` representing the value of the field in the document.
10315+ */
10316+ export function getField ( fieldName : string , keyExpr : Expression ) : Expression ;
10317+ export function getField (
10318+ fieldOrExpr : string | Expression ,
10319+ keyOrExpr : string | Expression ,
10320+ ) : Expression {
10321+ return fieldOrExpression ( fieldOrExpr ) . getField ( keyOrExpr ) ;
10322+ }
10323+
10324+ /**
10325+ * @internal
10326+ * Expression representing a variable reference. This evaluates to the value of a variable
10327+ * defined in a pipeline.
10328+ */
10329+ export class VariableExpression extends Expression {
10330+ expressionType : firestore . Pipelines . ExpressionType = 'Variable' ;
10331+
10332+ /**
10333+ * @hideconstructor
10334+ */
10335+ constructor ( private readonly name : string ) {
10336+ super ( ) ;
10337+ }
10338+
10339+ /**
10340+ * @internal
10341+ */
10342+ _toProto ( _serializer : Serializer ) : api . IValue {
10343+ return {
10344+ variableReferenceValue : this . name ,
10345+ } ;
10346+ }
10347+
10348+ /**
10349+ * @internal
10350+ */
10351+ _validateUserData ( _ignoreUndefinedProperties : boolean ) : void { }
10352+ }
10353+
10354+ /**
10355+ * Creates an expression that retrieves the value of a variable bound via `define()`.
10356+ *
10357+ * @example
10358+ * ```typescript
10359+ * db.pipeline().collection("products")
10360+ * .define(
10361+ * field("price").multiply(0.9).as("discountedPrice"),
10362+ * field("stock").add(10).as("newStock")
10363+ * )
10364+ * .where(variable("discountedPrice").lessThan(100))
10365+ * .select(field("name"), variable("newStock"));
10366+ * ```
10367+ *
10368+ * @param name - The name of the variable to retrieve.
10369+ * @returns An `Expression` representing the variable's value.
10370+ */
10371+ export function variable ( name : string ) : Expression {
10372+ return new VariableExpression ( name ) ;
10373+ }
10374+
10375+ /**
10376+ * Creates an expression that represents the current document being processed.
10377+ *
10378+ * @example
10379+ * ```typescript
10380+ * // Define the current document as a variable "doc"
10381+ * firestore.pipeline().collection("books")
10382+ * .define(currentDocument().as("doc"))
10383+ * // Access a field from the defined document variable
10384+ * .select(variable("doc").getField("title"));
10385+ * ```
10386+ *
10387+ * @returns An `Expression` representing the current document.
10388+ */
10389+ export function currentDocument ( ) : Expression {
10390+ return new FunctionExpression ( 'current_document' , [ ] ) ;
10391+ }
10392+
10393+ /**
10394+ * @internal
10395+ */
10396+ class PipelineValueExpression extends Expression {
10397+ expressionType : firestore . Pipelines . ExpressionType = 'PipelineValue' ;
10398+
10399+ /**
10400+ * @hideconstructor
10401+ */
10402+ constructor ( private readonly pipeline : firestore . Pipelines . Pipeline ) {
10403+ super ( ) ;
10404+ }
10405+
10406+ /**
10407+ * @internal
10408+ */
10409+ _toProto ( serializer : Serializer ) : api . IValue {
10410+ return {
10411+ // Casting to bypass type checking becuase _validateUserData does not exist in the public types
10412+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10413+ pipelineValue : ( this . pipeline as Pipeline ) . _toProto ( serializer ) ,
10414+ } ;
10415+ }
10416+
10417+ /**
10418+ * @internal
10419+ */
10420+ _validateUserData ( _ignoreUndefinedProperties : boolean ) : void {
10421+ // Casting to bypass type checking becuase _validateUserData does not exist in the public types
10422+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10423+ ( this . pipeline as any ) . _validateUserData ( 'PipelineValueExpression' ) ;
10424+ }
10425+ }
10426+
10427+ /**
10428+ * @internal
10429+ */
10430+ export function pipelineValue (
10431+ pipeline : firestore . Pipelines . Pipeline ,
10432+ ) : Expression {
10433+ return new PipelineValueExpression ( pipeline ) ;
10434+ }
10435+
1024110436// TODO(new-expression): Add new top-level expression function definitions above this line
1024210437
1024310438/**
0 commit comments