4848)
4949
5050
51+ class TimeUnit (str , Enum ):
52+ """Enumeration of the different time units supported by the Firestore backend."""
53+
54+ MICROSECOND = "microsecond"
55+ MILLISECOND = "millisecond"
56+ SECOND = "second"
57+ MINUTE = "minute"
58+ HOUR = "hour"
59+ DAY = "day"
60+
61+
62+ class TimeGranularity (str , Enum ):
63+ """Enumeration of the different time granularities supported by the Firestore backend."""
64+
65+ # Inherit from TimeUnit
66+ MICROSECOND = TimeUnit .MICROSECOND .value
67+ MILLISECOND = TimeUnit .MILLISECOND .value
68+ SECOND = TimeUnit .SECOND .value
69+ MINUTE = TimeUnit .MINUTE .value
70+ HOUR = TimeUnit .HOUR .value
71+ DAY = TimeUnit .DAY .value
72+
73+ # Additional granularities
74+ WEEK = "week"
75+ WEEK_MONDAY = "week(monday)"
76+ WEEK_TUESDAY = "week(tuesday)"
77+ WEEK_WEDNESDAY = "week(wednesday)"
78+ WEEK_THURSDAY = "week(thursday)"
79+ WEEK_FRIDAY = "week(friday)"
80+ WEEK_SATURDAY = "week(saturday)"
81+ WEEK_SUNDAY = "week(sunday)"
82+ ISOWEEK = "isoweek"
83+ MONTH = "month"
84+ QUARTER = "quarter"
85+ YEAR = "year"
86+ ISOYEAR = "isoyear"
87+
88+
89+ class TimePart (str , Enum ):
90+ """Enumeration of the different time parts supported by the Firestore backend."""
91+
92+ # Inherit from TimeUnit
93+ MICROSECOND = TimeUnit .MICROSECOND .value
94+ MILLISECOND = TimeUnit .MILLISECOND .value
95+ SECOND = TimeUnit .SECOND .value
96+ MINUTE = TimeUnit .MINUTE .value
97+ HOUR = TimeUnit .HOUR .value
98+ DAY = TimeUnit .DAY .value
99+
100+ # Inherit from TimeGranularity
101+ WEEK = TimeGranularity .WEEK .value
102+ WEEK_MONDAY = TimeGranularity .WEEK_MONDAY .value
103+ WEEK_TUESDAY = TimeGranularity .WEEK_TUESDAY .value
104+ WEEK_WEDNESDAY = TimeGranularity .WEEK_WEDNESDAY .value
105+ WEEK_THURSDAY = TimeGranularity .WEEK_THURSDAY .value
106+ WEEK_FRIDAY = TimeGranularity .WEEK_FRIDAY .value
107+ WEEK_SATURDAY = TimeGranularity .WEEK_SATURDAY .value
108+ WEEK_SUNDAY = TimeGranularity .WEEK_SUNDAY .value
109+ ISOWEEK = TimeGranularity .ISOWEEK .value
110+ MONTH = TimeGranularity .MONTH .value
111+ QUARTER = TimeGranularity .QUARTER .value
112+ YEAR = TimeGranularity .YEAR .value
113+ ISOYEAR = TimeGranularity .ISOYEAR .value
114+
115+ # Additional parts
116+ DAY_OF_WEEK = "dayofweek"
117+ DAY_OF_YEAR = "dayofyear"
118+
119+
51120class Ordering :
52121 """Represents the direction for sorting results in a pipeline."""
53122
@@ -90,6 +159,31 @@ def _to_pb(self) -> Value:
90159 )
91160
92161
162+ class Type (str , Enum ):
163+ """Enumeration of the different types generated by the Firestore backend."""
164+
165+ NULL = "null"
166+ ARRAY = "array"
167+ BOOLEAN = "boolean"
168+ BYTES = "bytes"
169+ TIMESTAMP = "timestamp"
170+ GEO_POINT = "geo_point"
171+ NUMBER = "number"
172+ INT32 = "int32"
173+ INT64 = "int64"
174+ FLOAT64 = "float64"
175+ DECIMAL128 = "decimal128"
176+ MAP = "map"
177+ REFERENCE = "reference"
178+ STRING = "string"
179+ VECTOR = "vector"
180+ MAX_KEY = "max_key"
181+ MIN_KEY = "min_key"
182+ OBJECT_ID = "object_id"
183+ REGEX = "regex"
184+ REQUEST_TIMESTAMP = "request_timestamp"
185+
186+
93187class Expression (ABC ):
94188 """Represents an expression that can be evaluated to a value within the
95189 execution of a pipeline.
@@ -120,6 +214,8 @@ def _cast_to_expr_or_convert_to_constant(
120214 """Convert arbitrary object to an Expression."""
121215 if isinstance (o , Expression ):
122216 return o
217+ if isinstance (o , Enum ):
218+ o = o .value
123219 if isinstance (o , dict ):
124220 return Map (o )
125221 if isinstance (o , list ):
@@ -2079,20 +2175,21 @@ def unix_seconds_to_timestamp(self) -> "Expression":
20792175
20802176 @expose_as_static
20812177 def timestamp_add (
2082- self , unit : Expression | str , amount : Expression | float
2178+ self , unit : TimeUnit | str | Expression , amount : Expression | float
20832179 ) -> "Expression" :
20842180 """Creates an expression that adds a specified amount of time to this timestamp expression.
20852181
20862182 Example:
2183+ >>> # Add 1.5 days to the 'timestamp' field using TimeUnit enum.
2184+ >>> Field.of("timestamp").timestamp_add(TimeUnit.DAY, 1.5)
20872185 >>> # Add a duration specified by the 'unit' and 'amount' fields to the 'timestamp' field.
20882186 >>> Field.of("timestamp").timestamp_add(Field.of("unit"), Field.of("amount"))
2089- >>> # Add 1.5 days to the 'timestamp' field.
2187+ >>> # Add 1.5 days to the 'timestamp' field using a string .
20902188 >>> Field.of("timestamp").timestamp_add("day", 1.5)
20912189
20922190 Args:
2093- unit: The expression or string evaluating to the unit of time to add, must be one of
2094- 'microsecond', 'millisecond', 'second', 'minute', 'hour', 'day'.
2095- amount: The expression or float representing the amount of time to add.
2191+ unit: The unit of time to add.
2192+ amount: The amount of time to add.
20962193
20972194 Returns:
20982195 A new `Expression` representing the resulting timestamp.
@@ -2108,20 +2205,21 @@ def timestamp_add(
21082205
21092206 @expose_as_static
21102207 def timestamp_subtract (
2111- self , unit : Expression | str , amount : Expression | float
2208+ self , unit : TimeUnit | str | Expression , amount : Expression | float
21122209 ) -> "Expression" :
21132210 """Creates an expression that subtracts a specified amount of time from this timestamp expression.
21142211
21152212 Example:
2213+ >>> # Subtract 2.5 hours from the 'timestamp' field using TimeUnit enum.
2214+ >>> Field.of("timestamp").timestamp_subtract(TimeUnit.HOUR, 2.5)
21162215 >>> # Subtract a duration specified by the 'unit' and 'amount' fields from the 'timestamp' field.
21172216 >>> Field.of("timestamp").timestamp_subtract(Field.of("unit"), Field.of("amount"))
2118- >>> # Subtract 2.5 hours from the 'timestamp' field.
2217+ >>> # Subtract 2.5 hours from the 'timestamp' field using a string .
21192218 >>> Field.of("timestamp").timestamp_subtract("hour", 2.5)
21202219
21212220 Args:
2122- unit: The expression or string evaluating to the unit of time to subtract, must be one of
2123- 'microsecond', 'millisecond', 'second', 'minute', 'hour', 'day'.
2124- amount: The expression or float representing the amount of time to subtract.
2221+ unit: The unit of time to subtract.
2222+ amount: The amount of time to subtract.
21252223
21262224 Returns:
21272225 A new `Expression` representing the resulting timestamp.
@@ -2206,6 +2304,163 @@ def as_(self, alias: str) -> "AliasedExpression":
22062304 """
22072305 return AliasedExpression (self , alias )
22082306
2307+ @expose_as_static
2308+ def cmp (self , other : Expression | CONSTANT_TYPE ) -> "Expression" :
2309+ """Creates an expression that compares this expression to another expression.
2310+
2311+ Returns an integer:
2312+ * -1 if this expression is less than the other
2313+ * 0 if they are equal
2314+ * 1 if this expression is greater than the other
2315+
2316+ Example:
2317+ >>> # Compare the 'price' field to 10
2318+ >>> Field.of("price").cmp(10)
2319+
2320+ Args:
2321+ other: The value to compare against.
2322+
2323+ Returns:
2324+ A new `Expression` representing the comparison operation.
2325+ """
2326+ return FunctionExpression (
2327+ "cmp" , [self , self ._cast_to_expr_or_convert_to_constant (other )]
2328+ )
2329+
2330+ @expose_as_static
2331+ def timestamp_trunc (
2332+ self ,
2333+ granularity : TimeGranularity | Expression | str ,
2334+ timezone : Expression | str | None = None ,
2335+ ) -> "Expression" :
2336+ """Creates an expression that truncates a timestamp to a specified granularity.
2337+
2338+ Example:
2339+ >>> # Truncate the 'createdAt' field to the day using TimeGranularity enum
2340+ >>> Field.of("createdAt").timestamp_trunc(TimeGranularity.DAY)
2341+ >>> # Truncate the 'createdAt' field to the day in the 'America/Los_Angeles' timezone
2342+ >>> Field.of("createdAt").timestamp_trunc(TimeGranularity.DAY, "America/Los_Angeles")
2343+ >>> # Truncate the 'createdAt' field to the day using a string
2344+ >>> Field.of("createdAt").timestamp_trunc("day")
2345+
2346+ Args:
2347+ granularity: The granularity to truncate to.
2348+ timezone: The optional timezone.
2349+
2350+ Returns:
2351+ A new `Expression` representing the timestamp_trunc operation.
2352+ """
2353+ args = [self , self ._cast_to_expr_or_convert_to_constant (granularity )]
2354+ if timezone is not None :
2355+ args .append (self ._cast_to_expr_or_convert_to_constant (timezone ))
2356+ return FunctionExpression ("timestamp_trunc" , args )
2357+
2358+ @expose_as_static
2359+ def timestamp_extract (
2360+ self ,
2361+ part : TimePart | str | Expression ,
2362+ timezone : str | Expression | None = None ,
2363+ ) -> "Expression" :
2364+ """Creates an expression that extracts a part of a timestamp.
2365+
2366+ Example:
2367+ >>> # Extract the year from the 'createdAt' field using TimePart enum
2368+ >>> Field.of("createdAt").timestamp_extract(TimePart.YEAR)
2369+ >>> # Extract the year from the 'createdAt' field in the 'America/Los_Angeles' timezone
2370+ >>> Field.of("createdAt").timestamp_extract(TimePart.YEAR, "America/Los_Angeles")
2371+ >>> # Extract the year from the 'createdAt' field using a string
2372+ >>> Field.of("createdAt").timestamp_extract("year")
2373+
2374+ Args:
2375+ part: The part to extract.
2376+ timezone: The optional timezone.
2377+
2378+ Returns:
2379+ A new `Expression` representing the timestamp_extract operation.
2380+ """
2381+ args = [self , self ._cast_to_expr_or_convert_to_constant (part )]
2382+ if timezone is not None :
2383+ args .append (self ._cast_to_expr_or_convert_to_constant (timezone ))
2384+ return FunctionExpression ("timestamp_extract" , args )
2385+
2386+ @expose_as_static
2387+ def timestamp_diff (
2388+ self , start : Expression | datetime .datetime , unit : TimeUnit | str | Expression
2389+ ) -> "Expression" :
2390+ """Creates an expression that computes the difference between two timestamps in the specified unit.
2391+
2392+ Example:
2393+ >>> # Compute the difference in days between the 'end' field and the 'start' field using TimeUnit enum
2394+ >>> Field.of("end").timestamp_diff(Field.of("start"), TimeUnit.DAY)
2395+ >>> # Compute the difference in days using a string
2396+ >>> Field.of("end").timestamp_diff(Field.of("start"), "day")
2397+
2398+ Args:
2399+ start: The start timestamp.
2400+ unit: The unit of time.
2401+
2402+ Returns:
2403+ A new `Expression` representing the timestamp_diff operation.
2404+ """
2405+ return FunctionExpression (
2406+ "timestamp_diff" ,
2407+ [
2408+ self ,
2409+ self ._cast_to_expr_or_convert_to_constant (start ),
2410+ self ._cast_to_expr_or_convert_to_constant (unit ),
2411+ ],
2412+ )
2413+
2414+ @expose_as_static
2415+ def if_null (self , * others : Expression | CONSTANT_TYPE ) -> "Expression" :
2416+ """Creates an expression that returns the first non-null expression from the provided arguments.
2417+
2418+ Example:
2419+ >>> # Return the 'nickname' field if not null, otherwise return 'firstName'
2420+ >>> Field.of("nickname").if_null(Field.of("firstName"))
2421+
2422+ Args:
2423+ *others: Additional expressions or constants to evaluate if the previous ones are null.
2424+
2425+ Returns:
2426+ A new `Expression` representing the if_null operation.
2427+ """
2428+ return FunctionExpression (
2429+ "if_null" ,
2430+ [self ] + [self ._cast_to_expr_or_convert_to_constant (o ) for o in others ],
2431+ )
2432+
2433+ @expose_as_static
2434+ def type (self ) -> "Expression" :
2435+ """Creates an expression that returns the data type of this expression's result as a string.
2436+
2437+ Example:
2438+ >>> # Get the type of the 'title' field
2439+ >>> Field.of("title").type()
2440+
2441+ Returns:
2442+ A new `Expression` representing the type operation.
2443+ """
2444+ return FunctionExpression ("type" , [self ])
2445+
2446+ @expose_as_static
2447+ def is_type (self , type_val : Type | str | Expression ) -> "BooleanExpression" :
2448+ """Creates an expression that checks if the result is of the specified type.
2449+
2450+ Example:
2451+ >>> # Check if the 'price' field is a number
2452+ >>> Field.of("price").is_type("number")
2453+
2454+ Args:
2455+ type_val: The type string or expression to check against.
2456+
2457+ Returns:
2458+ A new `BooleanExpression` representing the is_type operation.
2459+ """
2460+ return BooleanExpression (
2461+ "is_type" , [self , self ._cast_to_expr_or_convert_to_constant (type_val )]
2462+ )
2463+
22092464
22102465class Constant (Expression , Generic [CONSTANT_TYPE ]):
22112466 """Represents a constant literal value in an expression."""
0 commit comments