private async Task <List <GroupAggregationResults> > PerformNetworkAggregateFind() { List <GroupAggregationResults> networkResults = new List <GroupAggregationResults>(); try { string mongoQuery = this.BuildMongoQuery(); NetworkRequest <JArray> request = Client.NetworkFactory.BuildGetAggregateRequest <JArray>(Collection, reduceFunction, mongoQuery, groupField, aggregateField); JArray results = await request.ExecuteAsync(); if (results != null) { foreach (JToken obj in results) { GroupAggregationResults gar = new GroupAggregationResults(); gar.GroupField = (obj as JObject).GetValue(groupField)?.ToString(); gar.Result = (obj as JObject).GetValue("result").ToObject <int>(); networkResults.Add(gar); } } } catch (KinveyException) { throw; } catch (Exception e) { throw new KinveyException(EnumErrorCategory.ERROR_DATASTORE_NETWORK, EnumErrorCode.ERROR_GENERAL, "Error in FindAggregateAsync() for network results.", e); } return(networkResults); }
public List <GroupAggregationResults> GetAggregateResult(EnumReduceFunction reduceFunction, string groupField, string aggregateField, Expression query) { List <GroupAggregationResults> localAggregateResults = new List <GroupAggregationResults>(); List <object> listValues = new List <object>(); PropertyInfo propInfo = typeof(T).GetRuntimeProperty(aggregateField); if (propInfo != null && IsTypeNumber(propInfo.PropertyType)) { int skipNumber = 0; int takeNumber = 0; bool sort = false; LambdaExpression exprSort = null; var lambdaExpr = ConvertQueryExpressionToFunction(query, ref skipNumber, ref takeNumber, ref sort, ref exprSort); if (String.IsNullOrEmpty(groupField)) { // Not grouping results be a specified field, so just aggregate over all entities // that pass through the query filter, if provided. GroupAggregationResults gar = new GroupAggregationResults(); gar.GroupField = null; // TODO do "skip" and "take" have to be taken into account in group aggregate functions? if (lambdaExpr != null) { listValues = (from t in dbConnectionSync.Table <T>().Where(lambdaExpr) select t.GetType().GetRuntimeProperty(aggregateField).GetValue(t, null)).ToList(); } else { listValues = (from t in dbConnectionSync.Table <T>() select t.GetType().GetRuntimeProperty(aggregateField).GetValue(t, null)).ToList(); } switch (reduceFunction) { case EnumReduceFunction.REDUCE_FUNCTION_SUM: foreach (int val in listValues) { gar.Result += val; } break; case EnumReduceFunction.REDUCE_FUNCTION_MIN: gar.Result = int.MaxValue; foreach (int val in listValues) { gar.Result = Math.Min(gar.Result, val); } break; case EnumReduceFunction.REDUCE_FUNCTION_MAX: gar.Result = int.MinValue; foreach (int val in listValues) { gar.Result = Math.Max(gar.Result, val); } break; case EnumReduceFunction.REDUCE_FUNCTION_AVERAGE: int count = 0; int total = 0; foreach (int val in listValues) { total += val; count++; } gar.Result = total / count; break; default: // TODO throw new KinveyException break; } localAggregateResults.Add(gar); } else { // A grouping field was supplied, so aggregate // result per group created on the group field IEnumerable <IGrouping <object, T> > grouplist; if (lambdaExpr != null) { grouplist = from t in dbConnectionSync.Table <T>().Where(lambdaExpr) group t by t.GetType().GetRuntimeProperty(groupField).GetValue(t, null); } else { grouplist = from t in dbConnectionSync.Table <T>() group t by t.GetType().GetRuntimeProperty(groupField).GetValue(t, null); } foreach (var grouping in grouplist) { int result = 0; listValues = (from x in grouping select x.GetType().GetRuntimeProperty(aggregateField).GetValue(x, null)).ToList(); GroupAggregationResults gar = new GroupAggregationResults(); gar.GroupField = grouping.Key.ToString(); switch (reduceFunction) { case EnumReduceFunction.REDUCE_FUNCTION_SUM: foreach (int val in listValues) { result += val; } break; case EnumReduceFunction.REDUCE_FUNCTION_MIN: result = int.MaxValue; foreach (int val in listValues) { result = Math.Min(result, val); } break; case EnumReduceFunction.REDUCE_FUNCTION_MAX: result = int.MinValue; foreach (int val in listValues) { result = Math.Max(result, val); } break; case EnumReduceFunction.REDUCE_FUNCTION_AVERAGE: int count = 0; int total = 0; foreach (int val in listValues) { total += val; count++; } result = total / count; break; default: // TODO throw new KinveyException break; } gar.Result = result; localAggregateResults.Add(gar); } } } return(localAggregateResults); }