protected internal virtual Expression VisitGroupBy(GroupByExpression node) { return node.Update( Visit(node.Source), Visit(node.KeySelector), VisitAndConvert(node.Accumulators, "VisitGroupBy")); }
private void TranslateGroupBy(GroupByExpression node) { Translate(node.Source); var groupValue = new BsonDocument(); var idValue = AggregateLanguageTranslator.Translate(node.KeySelector); groupValue.Add("_id", idValue); foreach (var accumulator in node.Accumulators) { var accumulatorValue = AggregateLanguageTranslator.Translate(accumulator); groupValue.Add(accumulator.FieldName, accumulatorValue); } _stages.Add(new BsonDocument("$group", groupValue)); }
private Expression VisitCorrelatedGroup(CorrelatedExpression node) { var groupExpression = (GroupByExpression)node.Expression; if (_accumulatorLookup != null && _accumulatorLookup.Contains(node.CorrelationId)) { var source = Visit(groupExpression.Source); var accumulators = new List<AccumulatorExpression>(); var fieldExpressions = new List<FieldExpression>(); var comparer = new ExpressionComparer(); foreach (var correlatedAccumulator in _accumulatorLookup[node.CorrelationId]) { var index = accumulators.FindIndex(x => comparer.Compare((Expression)x, correlatedAccumulator.Expression)); FieldExpression fieldExpression; if (index == -1) { var accumulator = (AccumulatorExpression)correlatedAccumulator.Expression; // TODO: might not need to do any renames... accumulator = new AccumulatorExpression( accumulator.Type, "__agg" + accumulators.Count, accumulator.Serializer, accumulator.AccumulatorType, accumulator.Argument); accumulators.Add(accumulator); fieldExpression = new FieldExpression(accumulator.FieldName, accumulator.Serializer); fieldExpressions.Add(fieldExpression); } else { fieldExpression = fieldExpressions[index]; } _accumulatorReplacementMap[correlatedAccumulator] = fieldExpression; } groupExpression = new GroupByExpression( groupExpression.Type, source, groupExpression.KeySelector, accumulators.AsReadOnly()); } return Visit(groupExpression); }