protected override Expression VisitSelect(SelectExpression select) { if (select.From.NodeType != (ExpressionType)MongoExpressionType.Collection) { throw new InvalidQueryException("The query is too complex to be processed by MongoDB. Try building a map-reduce query by hand or simplifying the query and using Linq-to-Objects."); } bool hasAggregates = new AggregateChecker().HasAggregates(select); if (select.GroupBy != null) { _isMapReduce = true; } else if (hasAggregates) { if (select.Fields.Count == 1 && select.Fields[0].Expression.NodeType == (ExpressionType)MongoExpressionType.Aggregate) { var aggregateExpression = (AggregateExpression)select.Fields[0].Expression; if (aggregateExpression.AggregateType == AggregateType.Count) { _isCount = true; } } if (!_isCount) { _isMapReduce = true; } } Visit(select.Where); return(select); }
private static bool CanMergeWithFrom(SelectExpression select, bool isTopLevel) { var fromSelect = select.From as SelectExpression; if (fromSelect == null) return false; var fromIsSimpleProjection = IsSimpleProjection(fromSelect); var fromIsNameMapProjection = IsNameMapProjection(fromSelect); if (!fromIsSimpleProjection && !fromIsNameMapProjection) return false; var selectIsNameMapProjection = IsNameMapProjection(select); var selectHasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0; var selectHasGroupBy = select.GroupBy != null; var selectHasAggregates = new AggregateChecker().HasAggregates(select); var fromHasOrderBy = fromSelect.OrderBy != null && fromSelect.OrderBy.Count > 0; var fromHasGroupBy = fromSelect.GroupBy != null; if (selectHasOrderBy && fromHasOrderBy) return false; if (selectHasGroupBy && fromHasGroupBy) return false; if(fromHasOrderBy && (selectHasGroupBy || selectHasAggregates || select.IsDistinct)) return false; if(fromHasGroupBy && select.Where != null) return false; if(fromSelect.Take != null && (select.Take != null || select.Skip != null || select.IsDistinct || selectHasAggregates || selectHasGroupBy)) return false; if(fromSelect.Skip != null && (select.Skip != null || select.IsDistinct || selectHasAggregates || selectHasGroupBy)) return false; if (fromSelect.IsDistinct && (select.Take != null || select.Skip != null || !selectIsNameMapProjection || selectHasGroupBy || selectHasAggregates || (selectHasOrderBy && !isTopLevel))) return false; return true; }
private static bool CanMergeWithFrom(SelectExpression select, bool isTopLevel) { var fromSelect = select.From as SelectExpression; if (fromSelect == null) { return(false); } var fromIsSimpleProjection = IsSimpleProjection(fromSelect); var fromIsNameMapProjection = IsNameMapProjection(fromSelect); if (!fromIsSimpleProjection && !fromIsNameMapProjection) { return(false); } var selectIsNameMapProjection = IsNameMapProjection(select); var selectHasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0; var selectHasGroupBy = select.GroupBy != null; var selectHasAggregates = new AggregateChecker().HasAggregates(select); var fromHasOrderBy = fromSelect.OrderBy != null && fromSelect.OrderBy.Count > 0; var fromHasGroupBy = fromSelect.GroupBy != null; if (selectHasOrderBy && fromHasOrderBy) { return(false); } if (selectHasGroupBy && fromHasGroupBy) { return(false); } if (fromHasOrderBy && (selectHasGroupBy || selectHasAggregates || select.IsDistinct)) { return(false); } if (fromHasGroupBy && select.Where != null) { return(false); } if (fromSelect.Take != null && (select.Take != null || select.Skip != null || select.IsDistinct || selectHasAggregates || selectHasGroupBy)) { return(false); } if (fromSelect.Skip != null && (select.Skip != null || select.IsDistinct || selectHasAggregates || selectHasGroupBy)) { return(false); } if (fromSelect.IsDistinct && (select.Take != null || select.Skip != null || !selectIsNameMapProjection || selectHasGroupBy || selectHasAggregates || (selectHasOrderBy && !isTopLevel))) { return(false); } return(true); }