@@ -1160,71 +1160,54 @@ def _build_pipeline(self, source: "PipelineSource"):
11601160
11611161 # "explicit_orders" are only those explicitly added by the user via order_by().
11621162 # We only generate existence filters for these fields.
1163- explicit_orders = self ._orders
1164- exists = []
1165- for order in explicit_orders :
1166- field = pipeline_expressions .Field .of (order .field .field_path )
1167- exists .append (field .exists ())
1168-
1169- # Add exists filters to match Query's implicit orderby semantics.
1170- if len (exists ) == 1 :
1171- ppl = ppl .where (exists [0 ])
1172- elif len (exists ) > 1 :
1173- ppl = ppl .where (pipeline_expressions .And (* exists ))
1163+ if self ._orders :
1164+ exists = [
1165+ pipeline_expressions .Field .of (o .field .field_path ).exists ()
1166+ for o in self ._orders
1167+ ]
1168+ ppl = ppl .where (
1169+ pipeline_expressions .And (* exists ) if len (exists ) > 1 else exists [0 ]
1170+ )
11741171
11751172 # "normalized_orders" includes both user-specified orders and implicit orders
11761173 # (e.g. __name__ or inequality fields) required by Firestore semantics.
11771174 normalized_orders = self ._normalize_orders ()
1178- orderings = []
1179- if normalized_orders :
1180- for order in normalized_orders :
1181- field = pipeline_expressions .Field .of (order .field .field_path )
1182- direction = (
1183- "ascending"
1184- if order .direction == StructuredQuery .Direction .ASCENDING
1185- else "descending"
1186- )
1187- orderings .append (pipeline_expressions .Ordering (field , direction ))
1175+ orderings = [
1176+ pipeline_expressions .Ordering (
1177+ pipeline_expressions .Field .of (o .field .field_path ),
1178+ "ascending"
1179+ if o .direction == StructuredQuery .Direction .ASCENDING
1180+ else "descending" ,
1181+ )
1182+ for o in normalized_orders
1183+ ]
11881184
1185+ # Apply cursors as filters.
11891186 if orderings :
1190- # If limit_to_last is set, we need to reverse the orderings to find the
1191- # "last" N documents (which effectively become the "first" N in reverse order).
1192- if self ._limit_to_last :
1193- actual_orderings = _reverse_orderings (orderings )
1194- ppl = ppl .sort (* actual_orderings )
1195-
1196- # Apply cursor conditions.
1197- # Cursors are translated into filter conditions (e.g., field > value)
1198- # based on the orderings.
1199- if self ._start_at :
1200- # Normalize cursors to get the raw values corresponding to the orders
1201- start_at_val = self ._normalize_cursor (self ._start_at , normalized_orders )
1202- ppl = ppl .where (
1203- _where_conditions_from_cursor (
1204- start_at_val , orderings , is_start_cursor = True
1187+ for cursor_data , is_start in [(self ._start_at , True ), (self ._end_at , False )]:
1188+ if cursor_data :
1189+ val = self ._normalize_cursor (cursor_data , normalized_orders )
1190+ ppl = ppl .where (
1191+ _where_conditions_from_cursor (val , orderings , is_start )
12051192 )
1206- )
12071193
1208- if self ._end_at :
1209- end_at_val = self ._normalize_cursor (self ._end_at , normalized_orders )
1210- ppl = ppl .where (
1211- _where_conditions_from_cursor (
1212- end_at_val , orderings , is_start_cursor = False
1213- )
1214- )
1194+ # Handle sort and limit, including limit_to_last semantics.
1195+ is_limit_to_last = self ._limit_to_last and bool (orderings )
12151196
1216- if not self ._limit_to_last :
1217- ppl = ppl .sort (* orderings )
1197+ if is_limit_to_last :
1198+ # If limit_to_last is set, we need to reverse the orderings to find the
1199+ # "last" N documents (which effectively become the "first" N in reverse order).
1200+ ppl = ppl .sort (* _reverse_orderings (orderings ))
1201+ elif orderings :
1202+ ppl = ppl .sort (* orderings )
12181203
1219- if self ._limit is not None :
1220- ppl = ppl .limit (self ._limit )
1204+ if self ._limit is not None and ( not self . _limit_to_last or orderings ) :
1205+ ppl = ppl .limit (self ._limit )
12211206
1207+ if is_limit_to_last :
12221208 # If we reversed the orderings for limit_to_last, we must now re-sort
12231209 # using the original orderings to return the results in the user-requested order.
1224- if self ._limit_to_last :
1225- ppl = ppl .sort (* orderings )
1226- elif self ._limit is not None and not self ._limit_to_last :
1227- ppl = ppl .limit (self ._limit )
1210+ ppl = ppl .sort (* orderings )
12281211
12291212 # Offset
12301213 if self ._offset :
0 commit comments