Use native driver LeftJoin to replace the cross-collection $lookup workaround

XMLWordPrintableJSON

    • Type: Task
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • None
    • Dotnet Drivers
    • None
    • None
    • None
    • None
    • None
    • None

      The MongoDB C# driver's LINQ v3 provider has no native LeftJoin translator (it dispatches on method name and only recognizes Join), and cannot express collection or multi-hop joins. To support cross-collection navigations (Include / ThenInclude / projected collections / filtered Include) and multi-collection joins, the EF Core provider currently works around this by:

      • rewriting EF's Queryable.LeftJoin into Queryable.Join with a LeftJoinResult<TOuter,TInner> result selector (the driver produces _outer/_inner fields), and
      • registering and emitting manual $lookup + $unwind aggregation stages where the driver join cannot express the shape.

      When the driver ships native LeftJoin support, a large amount of this workaround code can be removed (the $lookup machinery) and the rest simplified (the LeftJoin-to-Join rewrite).

      To make the eventual removal legible, the workaround code has been quarantined into partial-class files, each carrying a TODO referencing this ticket:

      Expected to be REMOVED ($lookup workaround):

      • Query/Expressions/MongoQueryExpression.Lookup.cs — pending-lookup state (_pendingLookups), dependency ordering (OrderLookupsByDependency), GetPendingLookups, AddLookup. (The _innerCollections tracking and UsesDriverJoinFields decision in the same file are the driver-native seam and will likely shrink rather than disappear.)
      • Query/Visitors/MongoProjectionBindingExpressionVisitor.Lookup.cs — the entire cross-collection Include binding cluster (TryBindProjectedCollectionNavigation/...Count, RewriteCollectionIncludeForLookup, Extract*Pipeline, AddReferenceLookupStages, WrapWithNestedCollectionIncludes, …). Sole entry points from the rest of the visitor are the two dispatch calls in VisitMethodCall.
      • Query/Visitors/MongoEFToLinqTranslatingExpressionVisitor.LeftJoin.cs — the $lookup-stage emission (AppendLookupStages, InjectAfterRootLookupStages, EmitLookupStages) and the Join-peeling helpers (StripJoinForLookup, IsJoinRelatedMethod, FindBaseSourceThroughJoin).

      Expected to REMAIN / SIMPLIFY (driver-native LeftJoin rewrite, in MongoEFToLinqTranslatingExpressionVisitor.LeftJoin.cs):

      • StripOuterSelectForJoin, RewriteLeftJoins, RewriteJoinNode, TryBuildDriverNativeLeftJoinPipeline, BuildLeftJoinResultSerializer, BuildProjectedLeftOuterJoin, RewriteLambdaForLeftJoinResult, TransparentIdentifierToLeftJoinResultRewriter, TryGetKeyFieldPath, TryGetPropertyNameFromKeySelector, AppendRawStage.

      Related dedicated types (also candidates for removal/simplification): Query/Expressions/LookupExpression.cs, Query/Expressions/EntityTypeObjectAccessExpression.cs, Query/LeftJoinResult.cs.

      The Visit / VisitMethodCall dispatch and the EF Core visitor overrides remain in the main visitor files and call into the helpers above.

      When this is picked up: confirm what the driver's native LeftJoin supports (collection navigations, multi-hop, filtered), delete the $lookup partial files and the fallback methods, remove the named dispatch call-sites, and simplify the remaining driver-native rewrite.

            Assignee:
            Unassigned
            Reporter:
            Arthur Vickers
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: