@@ -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 * @beta
@@ -3071,6 +3072,23 @@ export abstract class Expression
30713072 ] ) . asBoolean ( ) ;
30723073 }
30733074
3075+ /**
3076+ * @beta
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 ( 'field' , [ this , valueToDefaultExpr ( key ) ] ) ;
3090+ }
3091+
30743092 // TODO(new-expression): Add new expression method definitions above this line
30753093
30763094 /**
@@ -10237,6 +10255,186 @@ export function isType(
1023710255 return fieldOrExpression ( fieldNameOrExpression ) . isType ( type ) ;
1023810256}
1023910257
10258+ /**
10259+ * @beta
10260+ * Creates an expression that returns the value of a field from a document that results from the evaluation of the expression.
10261+ *
10262+ * @example
10263+ * ```typescript
10264+ * // Get the value of the "city" field in the "address" document.
10265+ * getField(field("address"), "city")
10266+ * ```
10267+ *
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+ * @beta
10274+ * Creates an expression that returns the value of a field from a document that results from the evaluation of the expression.
10275+ *
10276+ * @example
10277+ * ```typescript
10278+ * // Get the value of the key resulting from the "addressField" variable in the "address" document.
10279+ * getField(field("address", variable("addressField")),
10280+ * ```
10281+ *
10282+ * @param key 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+ * @beta
10291+ * Creates an expression that returns the value of a field from the document with the given field name.
10292+ *
10293+ * @example
10294+ * ```typescript
10295+ * // Get the value of the "city" field in the "address" document.
10296+ * getField("address", "city")
10297+ * ```
10298+ *
10299+ * @param key The field to access in the document.
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+ * @beta
10305+ * Creates an expression that returns the value of a field from the document with the given field name.
10306+ *
10307+ * @example
10308+ * ```typescript
10309+ * // Get the value of the "city" field in the "address" document.
10310+ * getField("address", variable("addressField"))
10311+ * ```
10312+ *
10313+ * @param key The field to access in the document.
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+ * @beta
10356+ * Creates an expression that retrieves the value of a variable bound via `define()`.
10357+ *
10358+ * @example
10359+ * ```typescript
10360+ * db.pipeline().collection("products")
10361+ * .define(
10362+ * field("price").multiply(0.9).as("discountedPrice"),
10363+ * field("stock").add(10).as("newStock")
10364+ * )
10365+ * .where(variable("discountedPrice").lessThan(100))
10366+ * .select(field("name"), variable("newStock"));
10367+ * ```
10368+ *
10369+ * @param name - The name of the variable to retrieve.
10370+ * @returns An `Expression` representing the variable's value.
10371+ */
10372+ export function variable ( name : string ) : Expression {
10373+ return new VariableExpression ( name ) ;
10374+ }
10375+
10376+ /**
10377+ * @beta
10378+ * Creates an expression that represents the current document being processed.
10379+ *
10380+ * @example
10381+ * ```typescript
10382+ * // Define the current document as a variable "doc"
10383+ * firestore.pipeline().collection("books")
10384+ * .define(currentDocument().as("doc"))
10385+ * // Access a field from the defined document variable
10386+ * .select(variable("doc").mapGet("title"));
10387+ * ```
10388+ *
10389+ * @returns An `Expression` representing the current document.
10390+ */
10391+ export function currentDocument ( ) : Expression {
10392+ return new FunctionExpression ( 'current_document' , [ ] ) ;
10393+ }
10394+
10395+ /**
10396+ * @internal
10397+ */
10398+ class PipelineValueExpression extends Expression {
10399+ expressionType : firestore . Pipelines . ExpressionType = 'PipelineValue' ;
10400+
10401+ /**
10402+ * @hideconstructor
10403+ */
10404+ constructor ( private readonly pipeline : firestore . Pipelines . Pipeline ) {
10405+ super ( ) ;
10406+ }
10407+
10408+ /**
10409+ * @internal
10410+ */
10411+ _toProto ( serializer : Serializer ) : api . IValue {
10412+ return {
10413+ // Casting to bypass type checking becuase _validateUserData does not exist in the public types
10414+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10415+ pipelineValue : ( this . pipeline as Pipeline ) . _toProto ( serializer ) ,
10416+ } ;
10417+ }
10418+
10419+ /**
10420+ * @internal
10421+ */
10422+ _validateUserData ( _ignoreUndefinedProperties : boolean ) : void {
10423+ // Casting to bypass type checking becuase _validateUserData does not exist in the public types
10424+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10425+ ( this . pipeline as any ) . _validateUserData ( 'PipelineValueExpression' ) ;
10426+ }
10427+ }
10428+
10429+ /**
10430+ * @internal
10431+ */
10432+ export function pipelineValue (
10433+ pipeline : firestore . Pipelines . Pipeline ,
10434+ ) : Expression {
10435+ return new PipelineValueExpression ( pipeline ) ;
10436+ }
10437+
1024010438// TODO(new-expression): Add new top-level expression function definitions above this line
1024110439
1024210440/**
0 commit comments