コード例 #1
0
 protected internal virtual Expression VisitPipeline(PipelineExpression node)
 {
     return(node.Update(
                Visit(node.Source),
                VisitAndConvert(node.Projector, nameof(VisitPipeline)),
                VisitResultOperator(node.ResultOperator)));
 }
コード例 #2
0
ファイル: BinderHelper.cs プロジェクト: RavenZZ/MDRelation
        public static WhereExpression BindWhere(PipelineExpression pipeline, IBindingContext bindingContext, LambdaExpression lambda)
        {
            bindingContext.AddExpressionMapping(lambda.Parameters[0], pipeline.Projector);

            var predicate = bindingContext.Bind(lambda.Body);

            return new WhereExpression(
                pipeline.Source,
                lambda.Parameters[0].Name,
                predicate);
        }
コード例 #3
0
ファイル: BinderHelper.cs プロジェクト: RavenZZ/MDRelation
        public static SelectExpression BindSelect(PipelineExpression pipeline, IBindingContext bindingContext, LambdaExpression lambda)
        {
            bindingContext.AddExpressionMapping(lambda.Parameters[0], pipeline.Projector);

            var selector = bindingContext.Bind(lambda.Body);

            return new SelectExpression(
                pipeline.Source,
                lambda.Parameters[0].Name,
                selector);
        }
コード例 #4
0
        protected internal override Expression VisitPipeline(PipelineExpression node)
        {
            // only do the root source of this one...
            var source = node.Source;
            var sourcedSource = source as ISourcedExpression;
            while (sourcedSource != null)
            {
                source = sourcedSource.Source;
                sourcedSource = source as ISourcedExpression;
            }

            var newSource = Visit(source);
            if (newSource != source)
            {
                return ExpressionReplacer.Replace(node, source, newSource);
            }

            return node;
        }
コード例 #5
0
        protected internal override Expression VisitPipeline(PipelineExpression node)
        {
            var source = node.Source;
            var sourcedSource = source as ISourcedExpression;
            while (sourcedSource != null)
            {
                source = sourcedSource.Source;
                sourcedSource = source as ISourcedExpression;
            }

            var newSource = Visit(source);
            PipelineExpression newNode = node;
            if (newSource != source)
            {
                newNode = (PipelineExpression)ExpressionReplacer.Replace(node, source, newSource);
            }

            return newNode.Update(
                newNode.Source,
                newNode.Projector,
                VisitResultOperator(newNode.ResultOperator));
        }
コード例 #6
0
        protected internal override Expression VisitPipeline(PipelineExpression node)
        {
            Guid correlationId;
            if (TryGetCorrelatedGroup(node.Source, out correlationId))
            {
                AccumulatorType accumulatorType;
                Expression argument;
                if (TryGetAccumulatorTypeAndArgument(node, out accumulatorType, out argument))
                {
                    var accumulator = new AccumulatorExpression(
                        node.Type,
                        "__agg" + _count++,
                        _bindingContext.GetSerializer(node.Type, argument),
                        accumulatorType,
                        argument);

                    return new CorrelatedExpression(
                        correlationId,
                        accumulator);
                }
            }

            return node;
        }
コード例 #7
0
        private BsonValue TranslatePipeline(PipelineExpression node)
        {
            if (node.ResultOperator == null)
            {
                return TranslateValue(node.Source);
            }

            BsonValue result;
            if (TryTranslateAvgResultOperator(node, out result) ||
                TryTranslateAllResultOperator(node, out result) ||
                TryTranslateAnyResultOperator(node, out result) ||
                TryTranslateContainsResultOperator(node, out result) ||
                TryTranslateCountResultOperator(node, out result) ||
                TryTranslateFirstResultOperator(node, out result) ||
                TryTranslateLastResultOperator(node, out result) ||
                TryTranslateMaxResultOperator(node, out result) ||
                TryTranslateMinResultOperator(node, out result) ||
                TryTranslateStdDevResultOperator(node, out result) ||
                TryTranslateSumResultOperator(node, out result))
            {
                return result;
            }

            var message = string.Format("The result operation {0} is not supported.", node.ResultOperator.GetType());
            throw new NotSupportedException(message);
        }
コード例 #8
0
        private void TranslatePipeline(PipelineExpression node)
        {
            Translate(node.Source);

            var serializationExpression = node.Projector as ISerializationExpression;
            var fieldExpression = node.Projector as FieldExpression; // not IFieldExpression
            if (fieldExpression != null)
            {
                var info = new BsonSerializationInfo(fieldExpression.FieldName, fieldExpression.Serializer, fieldExpression.Serializer.ValueType);

                // We are projecting a field, however the server only responds
                // with documents. So we'll create a projector that reads a document
                // and then projects the field out of it.
                var parameter = Expression.Parameter(typeof(ProjectedObject), "document");
                var projector = Expression.Lambda(
                    Expression.Call(
                        parameter,
                        "GetValue",
                        new Type[] { info.Serializer.ValueType },
                        Expression.Constant(info.ElementName),
                        Expression.Constant(info.Serializer.ValueType.GetDefaultValue(), typeof(object))),
                    parameter);
                var innerSerializer = new ProjectedObjectDeserializer(new[] { info });
                _outputSerializer = (IBsonSerializer)Activator.CreateInstance(
                    typeof(ProjectingDeserializer<,>).MakeGenericType(typeof(ProjectedObject), info.Serializer.ValueType),
                    new object[]
                        {
                                innerSerializer,
                                projector.Compile()
                        });
            }
            else if (serializationExpression != null)
            {
                _outputSerializer = serializationExpression.Serializer;
            }
            else
            {
                throw new NotSupportedException();
            }

            _resultTransformer = node.ResultOperator as IResultTransformer;
        }
コード例 #9
0
 protected internal virtual Expression VisitPipeline(PipelineExpression node)
 {
     return node.Update(
         Visit(node.Source),
         Visit(node.Projector),
         VisitResultOperator(node.ResultOperator));
 }
コード例 #10
0
        private bool TryTranslateSumResultOperator(PipelineExpression node, out BsonValue result)
        {
            var resultOperator = node.ResultOperator as SumResultOperator;
            if (resultOperator != null)
            {
                result = new BsonDocument("$sum", TranslateValue(node.Source));
                return true;
            }

            result = null;
            return false;
        }
コード例 #11
0
        private bool TryTranslateStdDevResultOperator(PipelineExpression node, out BsonValue result)
        {
            var resultOperator = node.ResultOperator as StandardDeviationResultOperator;
            if (resultOperator != null)
            {
                var name = resultOperator.IsSample ? "$stdDevSamp" : "$stdDevPop";
                result = new BsonDocument(name, TranslateValue(node.Source));
                return true;
            }

            result = null;
            return false;
        }
コード例 #12
0
        private bool TryTranslateLastResultOperator(PipelineExpression node, out BsonValue result)
        {
            var resultOperator = node.ResultOperator as LastResultOperator;
            if (resultOperator != null)
            {
                result = new BsonDocument("$arrayElemAt", new BsonArray
                {
                    TranslateValue(node.Source),
                    -1
                });
                return true;
            }

            result = null;
            return false;
        }
コード例 #13
0
        private bool TryTranslateContainsResultOperator(PipelineExpression node, out BsonValue result)
        {
            var resultOperator = node.ResultOperator as ContainsResultOperator;
            if (resultOperator != null)
            {
                var source = TranslateValue(node.Source);
                var value = TranslateValue(resultOperator.Value);

                result = new BsonDocument("$anyElementTrue", new BsonDocument("$map", new BsonDocument
                {
                    { "input", source },
                    { "as", "x" },
                    { "in", new BsonDocument("$eq", new BsonArray(new [] { "$$x", value})) }
                }));
                return true;
            }

            result = null;
            return false;
        }
コード例 #14
0
        private bool TryTranslateAnyResultOperator(PipelineExpression node, out BsonValue result)
        {
            var resultOperator = node.ResultOperator as AnyResultOperator;
            if (resultOperator != null)
            {
                var whereExpression = node.Source as WhereExpression;

                if (whereExpression == null)
                {
                    result = new BsonDocument("$gt", new BsonArray(new BsonValue[]
                {
                    new BsonDocument("$size", TranslateValue(node.Source)),
                    0
                }));
                    return true;
                }
                else
                {
                    var inValue = TranslateValue(FieldNamePrefixer.Prefix(whereExpression.Predicate, "$" + whereExpression.ItemName));

                    result = new BsonDocument("$map", new BsonDocument
                    {
                        { "input", TranslateValue(whereExpression.Source) },
                        { "as", whereExpression.ItemName },
                        { "in", inValue}
                    });

                    result = new BsonDocument("$anyElementTrue", result);
                    return true;
                }
            }

            result = null;
            return false;
        }
コード例 #15
0
        protected internal override Expression VisitPipeline(PipelineExpression node)
        {
            _accumulatorLookup = AccumulatorGatherer.Gather(node.Source).ToLookup(x => x.CorrelationId);

            return base.VisitPipeline(node);
        }
コード例 #16
0
        private bool TryTranslateAggregateResultOperator(PipelineExpression node, out BsonValue result)
        {
            result = null;
            var resultOperator = node.ResultOperator as AggregateResultOperator;
            if (resultOperator != null)
            {
                var input = TranslateValue(node.Source);
                var initialValue = TranslateValue(resultOperator.Seed);
                var inValue = TranslateValue(resultOperator.Reducer);

                result = new BsonDocument("$reduce", new BsonDocument
                {
                    { "input", input },
                    { "initialValue", initialValue },
                    { "in", inValue }
                });

                if (resultOperator.Finalizer != null)
                {
                    inValue = TranslateValue(resultOperator.Finalizer);
                    result = new BsonDocument("$let", new BsonDocument
                    {
                        { "vars", new BsonDocument(resultOperator.ItemName, result) },
                        { "in", inValue }
                    });
                }
                return true;
            }

            return false;
        }
コード例 #17
0
 protected internal virtual Expression VisitPipeline(PipelineExpression node)
 {
     return(node.Update(
                Visit(node.Source),
                Visit(node.Projector)));
 }
コード例 #18
0
        private bool TryGetAccumulatorTypeAndArgument(PipelineExpression node, out AccumulatorType accumulatorType, out Expression argument)
        {
            if (node.ResultOperator == null)
            {
                var distinct = node.Source as DistinctExpression;
                if (distinct != null)
                {
                    accumulatorType = AccumulatorType.AddToSet;
                    argument = GetAccumulatorArgument(distinct.Source);
                    return true;
                }

                accumulatorType = AccumulatorType.Push;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }

            var resultOperator = node.ResultOperator;
            if (resultOperator is AverageResultOperator)
            {
                accumulatorType = AccumulatorType.Average;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is CountResultOperator)
            {
                accumulatorType = AccumulatorType.Sum;
                argument = Expression.Constant(1);
                return true;
            }
            if (resultOperator is FirstResultOperator)
            {
                accumulatorType = AccumulatorType.First;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is LastResultOperator)
            {
                accumulatorType = AccumulatorType.Last;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is MaxResultOperator)
            {
                accumulatorType = AccumulatorType.Max;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is MinResultOperator)
            {
                accumulatorType = AccumulatorType.Min;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is StandardDeviationResultOperator)
            {
                var isSample = ((StandardDeviationResultOperator)resultOperator).IsSample;
                accumulatorType = isSample ? AccumulatorType.StandardDeviationSample : AccumulatorType.StandardDeviationPopulation;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is SumResultOperator)
            {
                accumulatorType = AccumulatorType.Sum;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is ArrayResultOperator)
            {
                accumulatorType = AccumulatorType.Push;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is HashSetResultOperator)
            {
                accumulatorType = AccumulatorType.AddToSet;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }
            if (resultOperator is ListResultOperator)
            {
                accumulatorType = AccumulatorType.Push;
                argument = GetAccumulatorArgument(node.Source);
                return true;
            }

            accumulatorType = 0;
            argument = null;
            return false;
        }