private BsonDocument TranslateProjectValue(Expression selector)
        {
            BsonDocument projectValue;
            var          result = AggregateLanguageTranslator.Translate(selector, _translationOptions);

            if (result.BsonType == BsonType.String)
            {
                // this means we got back a field expression prefixed with a $ sign.
                projectValue = new BsonDocument(result.ToString().Substring(1), 1);
            }
            else if (result.BsonType == BsonType.Document)
            {
                projectValue = (BsonDocument)result;
            }
            else
            {
                throw new NotSupportedException($"The expression {selector.ToString()} is not supported.");
            }

            if (!projectValue.Contains("_id"))
            {
                projectValue.Add("_id", 0);
            }

            return(projectValue);
        }
        private void VisitDistinct(DistinctExpression node)
        {
            Visit(node.Source);

            var id = new BsonDocument("_id", AggregateLanguageTranslator.Translate(node.Selector));

            _stages.Add(new BsonDocument("$group", id));
        }
        public static BsonValue Translate <TSource, TResult>(
            Expression <Func <TSource, TResult> > expression,
            IBsonSerializer <TSource> sourceSerializer,
            IBsonSerializerRegistry serializerRegistry,
            ExpressionTranslationOptions translationOptions)
        {
            var bindingContext  = new PipelineBindingContext(serializerRegistry);
            var boundExpression = BindResult(bindingContext, expression, sourceSerializer);

            return(AggregateLanguageTranslator.Translate(boundExpression, translationOptions));
        }
예제 #4
0
        public static BsonDocument TranslateProject(Expression expression, ExpressionTranslationOptions translationOptions)
        {
            var projection = (BsonDocument)AggregateLanguageTranslator.Translate(expression, translationOptions);

            if (!projection.Contains("_id"))
            {
                projection.Add("_id", 0);
            }

            return(projection);
        }
        private void VisitRootAccumulator(RootAccumulatorExpression node)
        {
            Visit(node.Source);

            var group = new BsonDocument("_id", BsonNull.Value);

            var serializationAccumulator = (SerializationExpression)node.Accumulator;

            group.Add(
                serializationAccumulator.SerializationInfo.ElementName,
                AggregateLanguageTranslator.Translate(serializationAccumulator.Expression));

            _stages.Add(new BsonDocument("$group", group));
        }
        private void TranslateGroupBy(GroupByExpression node)
        {
            Translate(node.Source);

            var groupValue = new BsonDocument();
            var idValue    = AggregateLanguageTranslator.Translate(node.KeySelector, _translationOptions);

            groupValue.Add("_id", idValue);
            foreach (var accumulator in node.Accumulators)
            {
                var accumulatorValue = AggregateLanguageTranslator.Translate(accumulator, _translationOptions);
                groupValue.Add(accumulator.FieldName, accumulatorValue);
            }

            _stages.Add(new BsonDocument("$group", groupValue));
        }
        private void VisitCorrelatedGroupBy(CorrelatedGroupByExpression node)
        {
            Visit(node.Source);

            var group = new BsonDocument();

            group.Add("_id", AggregateLanguageTranslator.Translate(node.Id));

            foreach (var accumulator in node.Accumulators)
            {
                var serializationExpression = (SerializationExpression)accumulator;
                group.Add(
                    serializationExpression.SerializationInfo.ElementName,
                    AggregateLanguageTranslator.Translate(serializationExpression.Expression));
            }

            _stages.Add(new BsonDocument("$group", group));
        }
        public static RenderedProjectionDefinition <TResult> Translate <TKey, TDocument, TResult>(Expression <Func <TDocument, TKey> > idProjector, Expression <Func <IGrouping <TKey, TDocument>, TResult> > groupProjector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
        {
            var bindingContext = new PipelineBindingContext(serializerRegistry);

            var keySelector          = BindKeySelector(bindingContext, idProjector, parameterSerializer);
            var boundGroupExpression = BindGroup(bindingContext, groupProjector, parameterSerializer, keySelector);

            var projectionSerializer = bindingContext.GetSerializer(boundGroupExpression.Type, boundGroupExpression);
            var projection           = AggregateLanguageTranslator.Translate(boundGroupExpression, translationOptions).AsBsonDocument;

            // must have an "_id" in a group document
            if (!projection.Contains("_id"))
            {
                var idProjection = AggregateLanguageTranslator.Translate(keySelector, translationOptions);
                projection.InsertAt(0, new BsonElement("_id", idProjection));
            }

            return(new RenderedProjectionDefinition <TResult>(projection, (IBsonSerializer <TResult>)projectionSerializer));
        }
        private void TranslateJoin(JoinExpression node)
        {
            Translate(node.Source);

            var joined = node.Joined as CollectionExpression;

            if (joined == null)
            {
                throw new NotSupportedException("Only a collection is allowed to be joined.");
            }

            var localFieldValue = AggregateLanguageTranslator.Translate(node.SourceKeySelector, _translationOptions);

            if (localFieldValue.BsonType != BsonType.String)
            {
                throw new NotSupportedException("Could not translate the local field.");
            }

            var localField = localFieldValue.ToString().Substring(1); // remove '$'

            var foreignFieldValue = AggregateLanguageTranslator.Translate(node.JoinedKeySelector, _translationOptions);

            if (foreignFieldValue.BsonType != BsonType.String)
            {
                throw new NotSupportedException("Could not translate the foreign field.");
            }

            var foreignField = foreignFieldValue.ToString().Substring(1); // remove '$'

            _stages.Add(new BsonDocument("$lookup", new BsonDocument
            {
                { "from", ((CollectionExpression)node.Joined).CollectionNamespace.CollectionName },
                { "localField", localField },
                { "foreignField", foreignField },
                { "as", node.JoinedItemName }
            }));

            _stages.Add(new BsonDocument("$unwind", "$" + node.JoinedItemName));
        }