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);
        }
Esempio n. 2
0
        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);
        }