private static AstPipeline TranslateSelectManyWithCollectionSelectorAndNonIdentityResultSelector( TranslationContext context, AstPipeline pipeline, AggregationExpression collectionSelectorTranslation, LambdaExpression resultSelectorLambda) { var sourceSerializer = pipeline.OutputSerializer; var collectionItemSerializer = ArraySerializerHelper.GetItemSerializer(collectionSelectorTranslation.Serializer); var resultSelectorSourceParameterExpression = resultSelectorLambda.Parameters[0]; var resultSelectorSourceAst = AstExpression.Var("ROOT", isCurrent: true); var resultSelectorSourceParameterSymbol = context.CreateSymbol(resultSelectorSourceParameterExpression, resultSelectorSourceAst, sourceSerializer, isCurrent: true); var resultSelectorCollectionItemParameterExpression = resultSelectorLambda.Parameters[1]; var resultSelectorCollectionItemParameterSymbol = context.CreateSymbol(resultSelectorCollectionItemParameterExpression, collectionItemSerializer); var resultSelectorContext = context.WithSymbols(resultSelectorSourceParameterSymbol, resultSelectorCollectionItemParameterSymbol); var resultSelectorTranslation = ExpressionToAggregationExpressionTranslator.Translate(resultSelectorContext, resultSelectorLambda.Body); var resultValueSerializer = resultSelectorTranslation.Serializer; var resultWrappedValueSerializer = WrappedValueSerializer.Create("_v", resultValueSerializer); var resultAst = AstExpression.Map( input: collectionSelectorTranslation.Ast, @as: resultSelectorCollectionItemParameterSymbol.Var, @in: resultSelectorTranslation.Ast); return(pipeline.AddStages( resultWrappedValueSerializer, AstStage.Project( AstProject.Set("_v", resultAst), AstProject.ExcludeId()), AstStage.Unwind("_v"))); }
private AstPipeline OptimizeGroupStage(AstPipeline pipeline, int i, AstGroupStage groupStage) { try { if (IsOptimizableGroupStage(groupStage)) { var followingStages = GetFollowingStagesToOptimize(pipeline, i + 1); if (followingStages == null) { return(pipeline); } var mappings = OptimizeGroupAndFollowingStages(groupStage, followingStages); if (mappings.Length > 0) { return((AstPipeline)AstNodeReplacer.Replace(pipeline, mappings)); } } } catch (UnableToRemoveReferenceToElementsException) { // wasn't able to optimize away all references to _elements } return(pipeline);
// public static methods public static AstPipeline Translate(TranslationContext context, Expression expression) { if (expression.NodeType == ExpressionType.Constant) { var query = (IQueryable)((ConstantExpression)expression).Value; var provider = (IMongoQueryProvider)query.Provider; return(AstPipeline.Empty(provider.CollectionDocumentSerializer)); } var methodCallExpression = (MethodCallExpression)expression; switch (methodCallExpression.Method.Name) { case "Densify": return(DensifyMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "Distinct": return(DistinctMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "GroupBy": return(GroupByMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "GroupJoin": return(GroupJoinMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "Join": return(JoinMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "OfType": return(OfTypeMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "OrderBy": case "OrderByDescending": case "ThenBy": case "ThenByDescending": return(OrderByMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "Sample": return(SampleMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "Select": return(SelectMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "SelectMany": return(SelectManyMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "Skip": return(SkipMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "Take": return(TakeMethodToPipelineTranslator.Translate(context, methodCallExpression)); case "Where": return(WhereMethodToPipelineTranslator.Translate(context, methodCallExpression)); } throw new ExpressionNotSupportedException(expression); }
public AstFacetStageFacet Update(AstPipeline pipeline) { if (pipeline == _pipeline) { return(this); } return(new AstFacetStageFacet(_outputField, pipeline)); }
public AstLookupStageUncorrelatedMatch Update(AstPipeline pipeline, IEnumerable <AstComputedField> let) { if (pipeline == _pipeline && let == _let) { return(this); } return(new AstLookupStageUncorrelatedMatch(pipeline, let)); }
public AstUnionWithStage Update(AstPipeline pipeline) { if (pipeline == _pipeline) { return(this); } return(new AstUnionWithStage(_collection, pipeline)); }
public static ExecutableQuery <TDocument, TOutput, TResult> Create <TDocument, TOutput, TResult>( IMongoCollection <TDocument> collection, AggregateOptions options, AstPipeline unoptimizedPipeline, IExecutableQueryFinalizer <TOutput, TResult> finalizer) { var pipeline = AstPipelineOptimizer.Optimize(unoptimizedPipeline); return(new ExecutableQuery <TDocument, TOutput, TResult>(collection, options, unoptimizedPipeline, pipeline, finalizer)); }
public static AstPipeline Optimize(AstPipeline pipeline) { var optimizer = new AstGroupPipelineOptimizer(); for (var i = 0; i < pipeline.Stages.Count; i++) { var stage = pipeline.Stages[i]; if (stage is AstGroupStage groupStage) { pipeline = optimizer.OptimizeGroupStage(pipeline, i, groupStage); } } return(pipeline); }
private static AstPipeline TranslateSelectManyWithCollectionSelectorAndIdentityResultSelector( AstPipeline pipeline, AggregationExpression collectionSelectorTranslation) { var collectionItemSerializer = ArraySerializerHelper.GetItemSerializer(collectionSelectorTranslation.Serializer); var resultValueSerializer = collectionItemSerializer; var resultWrappedValueSerializer = WrappedValueSerializer.Create("_v", resultValueSerializer); return(pipeline.AddStages( resultWrappedValueSerializer, AstStage.Project( AstProject.Set("_v", collectionSelectorTranslation.Ast), AstProject.ExcludeId()), AstStage.Unwind("_v"))); }
static List <AstStage> GetFollowingStagesToOptimize(AstPipeline pipeline, int from) { var stages = new List <AstStage>(); for (var j = from; j < pipeline.Stages.Count; j++) { var stage = pipeline.Stages[j]; if (StageCanBeOptimized(stage)) { stages.Add(stage); } if (IsLastStageThatCanBeOptimized(stage)) { return(stages); } } return(null);
private static AstPipeline TranslateSelectMany( TranslationContext context, AstPipeline pipeline, ReadOnlyCollection <Expression> arguments) { var sourceSerializer = pipeline.OutputSerializer; var selectorLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true); var resultValueSerializer = ArraySerializerHelper.GetItemSerializer(selectorTranslation.Serializer); var resultWrappedValueSerializer = WrappedValueSerializer.Create("_v", resultValueSerializer); pipeline = pipeline.AddStages( resultWrappedValueSerializer, AstStage.Project( AstProject.Set("_v", selectorTranslation.Ast), AstProject.ExcludeId()), AstStage.Unwind("_v")); return(pipeline); }
private static AstPipeline TranslateSelectManyWithCollectionSelectorAndResultSelector( TranslationContext context, AstPipeline pipeline, ReadOnlyCollection <Expression> arguments) { var sourceSerializer = pipeline.OutputSerializer; var collectionSelectorLambda = ExpressionHelper.UnquoteLambda(arguments[1]); var collectionSelectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, collectionSelectorLambda, sourceSerializer, asRoot: true); var resultSelectorLambda = ExpressionHelper.UnquoteLambda(arguments[2]); if (resultSelectorLambda.Body == resultSelectorLambda.Parameters[1]) { // special case identity resultSelector: (x, y) => y return(TranslateSelectManyWithCollectionSelectorAndIdentityResultSelector(pipeline, collectionSelectorTranslation)); } else { return(TranslateSelectManyWithCollectionSelectorAndNonIdentityResultSelector(context, pipeline, collectionSelectorTranslation, resultSelectorLambda)); } }
private static AstPipeline TranslateResultSelector( TranslationContext context, AstPipeline pipeline, ReadOnlyCollection <Expression> arguments, IBsonSerializer keySerializer, IBsonSerializer elementSerializer) { var resultSelectorLambda = ExpressionHelper.UnquoteLambda(arguments.Last()); var root = AstExpression.Var("ROOT", isCurrent: true); var keyParameter = resultSelectorLambda.Parameters[0]; var keyField = AstExpression.GetField(root, "_id"); var keySymbol = context.CreateSymbol(keyParameter, keyField, keySerializer); var elementsParameter = resultSelectorLambda.Parameters[1]; var elementsField = AstExpression.GetField(root, "_elements"); var elementsSerializer = IEnumerableSerializer.Create(elementSerializer); var elementsSymbol = context.CreateSymbol(elementsParameter, elementsField, elementsSerializer); var resultSelectContext = context.WithSymbols(keySymbol, elementsSymbol); var resultSelectorTranslation = ExpressionToAggregationExpressionTranslator.Translate(resultSelectContext, resultSelectorLambda.Body); var(projectStage, projectionSerializer) = ProjectionHelper.CreateProjectStage(resultSelectorTranslation); return(pipeline.AddStages(projectionSerializer, projectStage)); }
public AstLookupStageUncorrelatedMatch(AstPipeline pipeline, IEnumerable <AstComputedField> let) { _pipeline = Ensure.IsNotNull(pipeline, nameof(pipeline)); _let = let?.AsReadOnlyList(); }
public AstUnionWithStage(string collection, AstPipeline pipeline) { _collection = Ensure.IsNotNull(collection, nameof(collection)); _pipeline = pipeline; }
public static AstStage UnionWith(string collection, AstPipeline pipeline) { return(new AstUnionWithStage(collection, pipeline)); }
public AstFacetStageFacet(string outputField, AstPipeline pipeline) { _outputField = Ensure.IsNotNull(outputField, nameof(outputField)); _pipeline = Ensure.IsNotNull(pipeline, nameof(pipeline)); }
public static AstPipeline Optimize(AstPipeline pipeline) { pipeline = AstGroupPipelineOptimizer.Optimize(pipeline); pipeline = AstSimplifier.SimplifyAndConvert(pipeline); return(pipeline); }