@@ -811,6 +811,89 @@ public static PipelineStageDefinition<TInput, TOutput> Lookup<TInput, TForeignDo
811
811
options ) ;
812
812
}
813
813
814
+ /// <summary>
815
+ /// Creates a $lookup stage.
816
+ /// </summary>
817
+ /// <typeparam name="TInput">The type of the input documents.</typeparam>
818
+ /// <typeparam name="TForeignDocument">The type of the foreign collection documents.</typeparam>
819
+ /// <typeparam name="TAsElement">The type of the as field elements.</typeparam>
820
+ /// <typeparam name="TAs">The type of the as field.</typeparam>
821
+ /// <typeparam name="TOutput">The type of the output documents.</typeparam>
822
+ /// <param name="foreignCollection">The foreign collection.</param>
823
+ /// <param name="let">The "let" definition.</param>
824
+ /// <param name="lookupPipeline">The lookup pipeline.</param>
825
+ /// <param name="as">The as field in <typeparamref name="TOutput" /> in which to place the results of the lookup pipeline.</param>
826
+ /// <param name="options">The options.</param>
827
+ /// <returns>The stage.</returns>
828
+ public static PipelineStageDefinition < TInput , TOutput > Lookup < TInput , TForeignDocument , TAsElement , TAs , TOutput > (
829
+ IMongoCollection < TForeignDocument > foreignCollection ,
830
+ BsonDocument let ,
831
+ PipelineDefinition < TForeignDocument , TAsElement > lookupPipeline ,
832
+ FieldDefinition < TOutput , TAs > @as ,
833
+ AggregateLookupOptions < TForeignDocument , TOutput > options = null )
834
+ where TAs : IEnumerable < TAsElement >
835
+ {
836
+ Ensure . IsNotNull ( foreignCollection , nameof ( foreignCollection ) ) ;
837
+ Ensure . IsNotNull ( lookupPipeline , nameof ( lookupPipeline ) ) ;
838
+ Ensure . IsNotNull ( @as , nameof ( @as ) ) ;
839
+
840
+ options = options ?? new AggregateLookupOptions < TForeignDocument , TOutput > ( ) ;
841
+ const string operatorName = "$lookup" ;
842
+ var stage = new DelegatedPipelineStageDefinition < TInput , TOutput > (
843
+ operatorName ,
844
+ ( inputSerializer , sr ) =>
845
+ {
846
+ var foreignSerializer = options . ForeignSerializer ?? foreignCollection . DocumentSerializer ?? inputSerializer as IBsonSerializer < TForeignDocument > ?? sr . GetSerializer < TForeignDocument > ( ) ;
847
+ var outputSerializer = options . ResultSerializer ?? inputSerializer as IBsonSerializer < TOutput > ?? sr . GetSerializer < TOutput > ( ) ;
848
+ var lookupPipelineDocuments = new BsonArray ( lookupPipeline . Render ( foreignSerializer , sr ) . Documents ) ;
849
+
850
+ var lookupBody = new BsonDocument
851
+ {
852
+ { "from" , foreignCollection . CollectionNamespace . CollectionName } ,
853
+ { "let" , let , let != null } ,
854
+ { "pipeline" , lookupPipelineDocuments } ,
855
+ { "as" , @as . Render ( outputSerializer , sr ) . FieldName }
856
+ } ;
857
+
858
+ return new RenderedPipelineStageDefinition < TOutput > ( operatorName , new BsonDocument ( operatorName , lookupBody ) , outputSerializer ) ;
859
+ } ) ;
860
+
861
+ return stage ;
862
+ }
863
+
864
+ /// <summary>
865
+ /// Creates a $lookup stage.
866
+ /// </summary>
867
+ /// <typeparam name="TInput">The type of the input documents.</typeparam>
868
+ /// <typeparam name="TForeignDocument">The type of the foreign collection documents.</typeparam>
869
+ /// <typeparam name="TAsElement">The type of the as field elements.</typeparam>
870
+ /// <typeparam name="TAs">The type of the as field.</typeparam>
871
+ /// <typeparam name="TOutput">The type of the output documents.</typeparam>
872
+ /// <param name="foreignCollection">The foreign collection.</param>
873
+ /// <param name="let">The "let" definition.</param>
874
+ /// <param name="lookupPipeline">The lookup pipeline.</param>
875
+ /// <param name="as">The as field in <typeparamref name="TOutput" /> in which to place the results of the lookup pipeline.</param>
876
+ /// <param name="options">The options.</param>
877
+ /// <returns>The stage.</returns>
878
+ public static PipelineStageDefinition < TInput , TOutput > Lookup < TInput , TForeignDocument , TAsElement , TAs , TOutput > (
879
+ IMongoCollection < TForeignDocument > foreignCollection ,
880
+ BsonDocument let ,
881
+ PipelineDefinition < TForeignDocument , TAsElement > lookupPipeline ,
882
+ Expression < Func < TOutput , TAs > > @as ,
883
+ AggregateLookupOptions < TForeignDocument , TOutput > options = null )
884
+ where TAs : IEnumerable < TAsElement >
885
+ {
886
+ Ensure . IsNotNull ( foreignCollection , nameof ( foreignCollection ) ) ;
887
+ Ensure . IsNotNull ( lookupPipeline , nameof ( lookupPipeline ) ) ;
888
+ Ensure . IsNotNull ( @as , nameof ( @as ) ) ;
889
+
890
+ return Lookup < TInput , TForeignDocument , TAsElement , TAs , TOutput > (
891
+ foreignCollection ,
892
+ let ,
893
+ lookupPipeline ,
894
+ new ExpressionFieldDefinition < TOutput , TAs > ( @as ) ) ;
895
+ }
896
+
814
897
/// <summary>
815
898
/// Creates a $match stage.
816
899
/// </summary>
0 commit comments