Example #1
0
        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")));
        }
Example #2
0
        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));
        }
Example #5
0
        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));
        }
Example #8
0
        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);
        }
Example #9
0
        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")));
        }
Example #10
0
            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);
Example #11
0
        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);
        }
Example #12
0
        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));
        }
Example #14
0
 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;
 }
Example #16
0
 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));
 }
Example #18
0
 public static AstPipeline Optimize(AstPipeline pipeline)
 {
     pipeline = AstGroupPipelineOptimizer.Optimize(pipeline);
     pipeline = AstSimplifier.SimplifyAndConvert(pipeline);
     return(pipeline);
 }