@@ -428,33 +428,31 @@ def _get_aggregate_expressions(self, expr):
428
428
stack .extend (expr .get_source_expressions ())
429
429
430
430
def get_project_fields (self , columns = None , ordering = None ):
431
- fields = {}
431
+ fields = defaultdict ( dict )
432
432
for name , expr in columns or []:
433
+ collection = expr .alias if isinstance (expr , Col ) else None
433
434
try :
434
- column = expr .target .column
435
- except AttributeError :
436
- # Generate the MQL for an annotation.
437
- try :
438
- fields [name ] = expr .as_mql (self , self .connection )
439
- except EmptyResultSet :
440
- fields [name ] = Value (False ).as_mql (self , self .connection )
441
- except FullResultSet :
442
- fields [name ] = Value (True ).as_mql (self , self .connection )
443
- else :
444
- # If name != column, then this is an annotatation referencing
445
- # another column.
446
- fields [name ] = 1 if name == column else f"${ column } "
447
- if fields :
448
- # Add related fields.
449
- for alias in self .query .alias_map :
450
- if self .query .alias_refcount [alias ] and self .collection_name != alias :
451
- fields [alias ] = 1
452
- # Add order_by() fields.
453
- for alias , expression in ordering or []:
454
- nested_entity = alias .split ("." , 1 )[0 ] if "." in alias else None
455
- if alias not in fields and nested_entity not in fields :
456
- fields [alias ] = expression .as_mql (self , self .connection )
457
- return fields
435
+ fields [collection ][name ] = (
436
+ 1
437
+ # For brevity/simplicity, project {"field_name": 1}
438
+ # instead of {"field_name": "$field_name"}.
439
+ if isinstance (expr , Col ) and name == expr .target .column
440
+ else expr .as_mql (self , self .connection )
441
+ )
442
+ except EmptyResultSet :
443
+ fields [collection ][name ] = Value (False ).as_mql (self , self .connection )
444
+ except FullResultSet :
445
+ fields [collection ][name ] = Value (True ).as_mql (self , self .connection )
446
+ # Annotations (stored in None) and the main collection's fields
447
+ # should appear in the top-level of the fields dict.
448
+ fields .update (fields .pop (None , {}))
449
+ fields .update (fields .pop (self .collection_name , {}))
450
+ # Add order_by() fields.
451
+ if fields and ordering :
452
+ fields .update ({alias : expr .as_mql (self , self .connection ) for alias , expr in ordering })
453
+ # Convert defaultdict to dict so it doesn't appear as
454
+ # "defaultdict(<CLASS 'dict'>, ..." in query logging.
455
+ return dict (fields )
458
456
459
457
def _get_ordering (self ):
460
458
"""
0 commit comments