From bcbbdd97be2cbe6b0dadb5400183e9128f2947ae Mon Sep 17 00:00:00 2001 From: Bart van den Burg Date: Fri, 26 Feb 2016 15:02:48 +0100 Subject: [PATCH] accept a list of group values --- Keen.NET.Test/QueryTest.cs | 40 +++++++++---------- Keen/KeenClient.cs | 82 +++++++++++++++++++++++++++++++++----- Keen/Query/IQueries.cs | 8 ++-- Keen/Query/Queries.cs | 32 +++++++-------- 4 files changed, 111 insertions(+), 51 deletions(-) diff --git a/Keen.NET.Test/QueryTest.cs b/Keen.NET.Test/QueryTest.cs index 52b81c3..5229998 100644 --- a/Keen.NET.Test/QueryTest.cs +++ b/Keen.NET.Test/QueryTest.cs @@ -147,7 +147,7 @@ public async void Query_ValidRelativeGroup_Success() { var client = new KeenClient(SettingsEnv); var timeframe = QueryRelativeTimeframe.PreviousNDays(2); - var groupby = "field1"; + var groupby = new List { "field1" }; IEnumerable> reply = new List>() { new QueryGroupValue( "0", "field1" ), @@ -162,7 +162,7 @@ public async void Query_ValidRelativeGroup_Success() It.Is(q => q == QueryType.Count()), It.Is(c => c == testCol), It.Is(p => p == ""), - It.Is(g => g == groupby), + It.Is>(g => g == groupby), It.Is(t => t == timeframe), It.Is>(f => f == null), It.Is(z => z == ""))) @@ -184,7 +184,7 @@ public async void Query_ValidRelativeGroupInterval_Success() var client = new KeenClient(SettingsEnv); var timeframe = QueryRelativeTimeframe.PreviousNDays(2); var interval = QueryInterval.EveryNHours(2); - var groupby = "field1"; + var groupby = new List { "field1" }; IEnumerable>>> reply = new List>>>() { @@ -214,7 +214,7 @@ public async void Query_ValidRelativeGroupInterval_Success() It.Is(q => q == QueryType.Count()), It.Is(c => c == testCol), It.Is(p => p == ""), - It.Is(g => g == groupby), + It.Is>(g => g == groupby), It.Is(t => t == timeframe), It.Is(i => i == interval), It.Is>(f => f == null), @@ -586,7 +586,7 @@ public async void SelectUnique_ValidRelativeGroup_Success() { var client = new KeenClient(SettingsEnv); var prop = "field1"; - var groupby = "field1"; + var groupby = new List { "field1" }; var timeframe = QueryRelativeTimeframe.PreviousNDays(5); IEnumerable> reply = new List>() { @@ -602,7 +602,7 @@ public async void SelectUnique_ValidRelativeGroup_Success() It.Is(q => q == QueryType.SelectUnique()), It.Is(c => c == testCol), It.Is(p => p == prop), - It.Is(g => g == groupby), + It.Is>(g => g == groupby), It.Is(t => t == timeframe), It.Is>(f => f == null), It.Is(t => t == "") @@ -691,7 +691,7 @@ public async void SelectUnique_ValidAbsoluteIntervalGroup_Success() var prop = "field1"; var timeframe = new QueryAbsoluteTimeframe(DateTime.Now.AddDays(-1), DateTime.Now); var interval = QueryInterval.EveryNHours(4); - var groupby = "field1"; + var groupby = new List { "field1" }; var resultl = "hello,goodbye,I'm late"; IEnumerable>>> result = @@ -721,7 +721,7 @@ public async void SelectUnique_ValidAbsoluteIntervalGroup_Success() It.Is(q => q == QueryType.SelectUnique()), It.Is(c => c == testCol), It.Is(p => p == prop), - It.Is(g => g == groupby), + It.Is>(g => g == groupby), It.Is(t => t == timeframe), It.Is(i => i == interval), It.Is>(f => f == null), @@ -956,7 +956,7 @@ public async void MultiAnalysis_ValidRelativeTimeFrame_Success() public async void MultiAnalysis_ValidGroupBy_Success() { var client = new KeenClient(SettingsEnv); - var groupby = "field1"; + var groupby = new List { "field1" }; IEnumerable param = new List() { new MultiAnalysisParam("first", MultiAnalysisParam.Metric.Count()), @@ -967,11 +967,11 @@ public async void MultiAnalysis_ValidGroupBy_Success() dict.Add("second", "fff"); dict.Add("third", "aaa"); dict.Add("first", "123"); - dict.Add(groupby, "123"); + dict.Add(string.Join(",", groupby), "123"); IEnumerable>> result = new List>>() { - new QueryGroupValue>(dict, groupby), - new QueryGroupValue>(dict, groupby), + new QueryGroupValue>(dict, string.Join(",", groupby)), + new QueryGroupValue>(dict, string.Join(",", groupby)), }; Mock queryMock = null; @@ -983,7 +983,7 @@ public async void MultiAnalysis_ValidGroupBy_Success() It.Is>(p => p == param), It.Is(t => t == null), It.Is>(f => f == null), - It.Is(g => g == groupby), + It.Is>(g => g == groupby), It.Is(tz => tz == "") )) .Returns(Task.FromResult(result)); @@ -1006,7 +1006,7 @@ public async void MultiAnalysis_ValidIntervalGroupBy_Success() var client = new KeenClient(SettingsEnv); var timeframe = QueryRelativeTimeframe.PreviousNDays(3); var interval = QueryInterval.Daily(); - var groupby = "field1"; + var groupby = new List { "field1" }; IEnumerable param = new List() { new MultiAnalysisParam("first", MultiAnalysisParam.Metric.Count()), @@ -1018,21 +1018,21 @@ public async void MultiAnalysis_ValidIntervalGroupBy_Success() dict.Add("second", "fff"); dict.Add("third", "aaa"); dict.Add("first", "123"); - dict.Add(groupby, "123"); + dict.Add(string.Join(",", groupby), "123"); IEnumerable>>>> result = new List>>>>() { new QueryIntervalValue>>>( new List>>(){ - new QueryGroupValue>(dict, groupby), - new QueryGroupValue>(dict, groupby) + new QueryGroupValue>(dict, string.Join(",", groupby)), + new QueryGroupValue>(dict, string.Join(",", groupby)) }, DateTime.Now, DateTime.Now.AddSeconds(2) ), new QueryIntervalValue>>>( new List>>(){ - new QueryGroupValue>(dict, groupby), - new QueryGroupValue>(dict, groupby) + new QueryGroupValue>(dict, string.Join(",", groupby)), + new QueryGroupValue>(dict, string.Join(",", groupby)) }, DateTime.Now, DateTime.Now.AddSeconds(2) ), @@ -1048,7 +1048,7 @@ public async void MultiAnalysis_ValidIntervalGroupBy_Success() It.Is(t => t == timeframe), It.Is(i=>i==interval), It.Is>(f => f == null), - It.Is(g => g == groupby), + It.Is>(g => g == groupby), It.Is(tz => tz == "") )) .Returns(Task.FromResult(result)); diff --git a/Keen/KeenClient.cs b/Keen/KeenClient.cs index 1ba9557..8932aa1 100644 --- a/Keen/KeenClient.cs +++ b/Keen/KeenClient.cs @@ -251,7 +251,7 @@ private async Task> AddEventsBulkAsync(string collectio if (!eventsInfo.Any()) return new List(); // Build a container object with a property to identify the collection - var jEvent = new JObject {{collection, JToken.FromObject(eventsInfo)}}; + var jEvent = new JObject { { collection, JToken.FromObject(eventsInfo) } }; // Use the bulk interface to add events return await Event.AddEvents(jEvent) @@ -362,12 +362,12 @@ private JObject PrepareUserObject(object eventInfo, IEnumerable addOns) // Ensure this event has a 'keen' object of the correct type if (null == jEvent.Property("keen")) jEvent.Add("keen", new JObject()); - else if (jEvent.Property("keen").Value.GetType() != typeof (JObject)) + else if (jEvent.Property("keen").Value.GetType() != typeof(JObject)) throw new KeenException(string.Format("Value of property \"keen\" must be an object, is {0}", jEvent.Property("keen").GetType())); - var keen = ((JObject) jEvent.Property("keen").Value); + var keen = ((JObject)jEvent.Property("keen").Value); if (addOns != null && addOns.Any()) keen.Add("addons", JArray.FromObject(addOns)); @@ -562,7 +562,7 @@ public string Query(QueryType queryType, string collection, string targetPropert /// The timezone to use when specifying a relative timeframe. Optional, may be blank. /// public async Task>> QueryGroupAsync(QueryType queryType, string collection, - string targetProperty, string groupBy, QueryTimeframe timeframe = null, + string targetProperty, IEnumerable groupBy, QueryTimeframe timeframe = null, IEnumerable filters = null, string timezone = "") { return @@ -571,6 +571,14 @@ public async Task>> QueryGroupAsync(QueryTyp .ConfigureAwait(false); } + public async Task>> QueryGroupAsync(QueryType queryType, string collection, + string targetProperty, string groupBy, QueryTimeframe timeframe = null, + IEnumerable filters = null, string timezone = "") + { + return await QueryGroupAsync(queryType, collection, targetProperty, new List { groupBy }, timeframe); + } + + /// /// Returns values collected by group. /// @@ -583,7 +591,7 @@ public async Task>> QueryGroupAsync(QueryTyp /// The timezone to use when specifying a relative timeframe. Optional, may be blank. /// public IEnumerable> QueryGroup(QueryType queryType, string collection, - string targetProperty, string groupBy, QueryTimeframe timeframe = null, + string targetProperty, IEnumerable groupBy, QueryTimeframe timeframe = null, IEnumerable filters = null, string timezone = "") { try @@ -597,6 +605,13 @@ public IEnumerable> QueryGroup(QueryType queryType, stri } } + public IEnumerable> QueryGroup(QueryType queryType, string collection, + string targetProperty, string groupBy, QueryTimeframe timeframe = null, + IEnumerable filters = null, string timezone = "") + { + return QueryGroup(queryType, collection, targetProperty, new List { groupBy }, timeframe); + } + /// /// Return values collected by time interval. /// @@ -658,7 +673,7 @@ public IEnumerable> QueryInterval(QueryType queryType /// The timezone to use when specifying a relative timeframe. Optional, may be blank. /// public async Task>>>> QueryIntervalGroupAsync - (QueryType queryType, string collection, string targetProperty, string groupBy, QueryTimeframe timeframe, + (QueryType queryType, string collection, string targetProperty, IEnumerable groupBy, QueryTimeframe timeframe, QueryInterval interval, IEnumerable filters = null, string timezone = "") { return @@ -666,6 +681,12 @@ public async Task>>>> QueryIntervalGroupAsync + (QueryType queryType, string collection, string targetProperty, string groupBy, QueryTimeframe timeframe, + QueryInterval interval, IEnumerable filters = null, string timezone = "") + { + return await QueryIntervalGroupAsync(queryType, collection, targetProperty, new List { groupBy }, timeframe, interval, filters, timezone); + } /// /// Returns items collected by time interval and group. @@ -680,7 +701,7 @@ public async TaskThe timezone to use when specifying a relative timeframe. Optional, may be blank. /// public IEnumerable>>> QueryIntervalGroup( - QueryType queryType, string collection, string targetProperty, string groupBy, QueryTimeframe timeframe, + QueryType queryType, string collection, string targetProperty, IEnumerable groupBy, QueryTimeframe timeframe, QueryInterval interval, IEnumerable filters = null, string timezone = "") { try @@ -695,6 +716,14 @@ public IEnumerable>>> Que } } + public IEnumerable>>> QueryIntervalGroup( + QueryType queryType, string collection, string targetProperty, string groupBy, QueryTimeframe timeframe, + QueryInterval interval, IEnumerable filters = null, string timezone = "") + { + return QueryIntervalGroup(queryType, collection, targetProperty, new List { groupBy }, timeframe, interval, filters, timezone); + } + + /// /// Extract full-form event data with all property values. /// @@ -820,7 +849,7 @@ public IDictionary QueryMultiAnalysis(string collection, /// public async Task>>> QueryMultiAnalysisGroupAsync( string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, - IEnumerable filters = null, string groupBy = "", string timezone = "") + IEnumerable filters = null, IEnumerable groupBy = null, string timezone = "") { return await @@ -828,6 +857,14 @@ public async Task>>> Que .ConfigureAwait(false); } + public async Task>>> QueryMultiAnalysisGroupAsync( + string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, + IEnumerable filters = null, string groupBy = "", string timezone = "") + { + return await QueryMultiAnalysisGroupAsync(collection, analysisParams, timeframe, filters, string.IsNullOrWhiteSpace(groupBy) ? null : new List { groupBy }, timezone); + } + + /// /// Run multiple types of analysis over the same data, /// grouped by the specified field. @@ -841,7 +878,7 @@ public async Task>>> Que /// public IEnumerable>> QueryMultiAnalysisGroup(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, - IEnumerable filters = null, string groupBy = "", string timezone = "") + IEnumerable filters = null, IEnumerable groupBy = null, string timezone = "") { try { @@ -855,6 +892,14 @@ public IEnumerable>> QueryMultiAnaly } } + public IEnumerable>> QueryMultiAnalysisGroup(string collection, + IEnumerable analysisParams, QueryTimeframe timeframe = null, + IEnumerable filters = null, string groupBy = "", string timezone = "") + { + return QueryMultiAnalysisGroup(collection, analysisParams, timeframe, filters, string.IsNullOrWhiteSpace(groupBy) ? null : new List { groupBy }, timezone); + } + + /// /// Run multiple types of analysis over the same data. /// Each item represents one interval. @@ -918,7 +963,7 @@ public IEnumerable>> QueryMultiAn public async Task>>>>> QueryMultiAnalysisIntervalGroupAsync(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, - string groupBy = "", string timezone = "") + IEnumerable groupBy = null, string timezone = "") { return await @@ -926,6 +971,14 @@ public async Task>>>>> + QueryMultiAnalysisIntervalGroupAsync(string collection, IEnumerable analysisParams, + QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, + string groupBy = "", string timezone = "") + { + return await QueryMultiAnalysisIntervalGroupAsync(collection, analysisParams, timeframe, interval, filters, string.IsNullOrWhiteSpace(groupBy) ? null : new List { groupBy }, timezone); + } + /// /// Run multiple types of analysis over the same data. /// Each item contains information about the groupings in that interval. @@ -941,7 +994,7 @@ public async Task>>>> QueryMultiAnalysisIntervalGroup(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, - string groupBy = "", string timezone = "") + IEnumerable groupBy = null, string timezone = "") { try { @@ -955,5 +1008,12 @@ public IEnumerable>>>> + QueryMultiAnalysisIntervalGroup(string collection, IEnumerable analysisParams, + QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, + string groupBy = "", string timezone = "") + { + return QueryMultiAnalysisIntervalGroup(collection, analysisParams, timeframe, interval, filters, string.IsNullOrWhiteSpace(groupBy) ? null : new List { groupBy }, timezone); + } } } \ No newline at end of file diff --git a/Keen/Query/IQueries.cs b/Keen/Query/IQueries.cs index 71565e8..7cebabf 100644 --- a/Keen/Query/IQueries.cs +++ b/Keen/Query/IQueries.cs @@ -17,14 +17,14 @@ public interface IQueries Task Metric(string queryName, Dictionary parms); Task Metric(QueryType queryType, string collection, string targetProperty, QueryTimeframe timeframe = null, IEnumerable filters = null, string timezone = ""); - Task>> Metric(QueryType queryType, string collection, string targetProperty, string groupBy, QueryTimeframe timeframe = null, IEnumerable filters = null, string timezone = ""); + Task>> Metric(QueryType queryType, string collection, string targetProperty, IEnumerable groupBy, QueryTimeframe timeframe = null, IEnumerable filters = null, string timezone = ""); Task>> Metric(QueryType queryType, string collection, string targetProperty, QueryTimeframe timeframe, QueryInterval interval, IEnumerable filters = null, string timezone = ""); - Task>>>> Metric(QueryType queryType, string collection, string targetProperty, string groupBy, QueryTimeframe timeframe, QueryInterval interval, IEnumerable filters = null, string timezone = ""); + Task>>>> Metric(QueryType queryType, string collection, string targetProperty, IEnumerable groupBy, QueryTimeframe timeframe, QueryInterval interval, IEnumerable filters = null, string timezone = ""); Task> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, IEnumerable filters = null, string timezone = ""); - Task>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, IEnumerable filters = null, string groupby = "", string timezone = ""); + Task>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, IEnumerable filters = null, IEnumerable groupby = null, string timezone = ""); Task>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, string timezone = ""); - Task>>>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, string groupby = "", string timezone = ""); + Task>>>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, IEnumerable groupby = null, string timezone = ""); Task> Extract(string collection, QueryTimeframe timeframe = null, IEnumerable filters = null, int latest = 0, string email = ""); diff --git a/Keen/Query/Queries.cs b/Keen/Query/Queries.cs index cd8d61e..6000471 100644 --- a/Keen/Query/Queries.cs +++ b/Keen/Query/Queries.cs @@ -112,7 +112,7 @@ public async Task Metric(QueryType queryType, string collection, string return result; } - public async Task>> Metric(QueryType queryType, string collection, string targetProperty, string groupby, QueryTimeframe timeframe = null, IEnumerable filters = null, string timezone = "") + public async Task>> Metric(QueryType queryType, string collection, string targetProperty, IEnumerable groupby, QueryTimeframe timeframe = null, IEnumerable filters = null, string timezone = "") { if (queryType == null) throw new ArgumentNullException("queryType"); @@ -120,13 +120,13 @@ public async Task>> Metric(QueryType queryTy throw new ArgumentNullException("collection"); if (string.IsNullOrWhiteSpace(targetProperty) && (queryType != QueryType.Count())) throw new ArgumentNullException("targetProperty"); - if (string.IsNullOrWhiteSpace(groupby)) - throw new ArgumentNullException("groupby", "groupby field name must be specified for a groupby query"); + if (!groupby.Any()) + throw new ArgumentNullException("groupby", "at least one groupby field name must be specified for a groupby query"); var parms = new Dictionary(); parms.Add(KeenConstants.QueryParmEventCollection, collection); parms.Add(KeenConstants.QueryParmTargetProperty, targetProperty); - parms.Add(KeenConstants.QueryParmGroupBy, groupby); + parms.Add(KeenConstants.QueryParmGroupBy, string.Join(",", groupby)); parms.Add(KeenConstants.QueryParmTimeframe, timeframe.ToSafeString()); parms.Add(KeenConstants.QueryParmTimezone, timezone); parms.Add(KeenConstants.QueryParmFilters, filters == null ? "" : JArray.FromObject(filters).ToString()); @@ -139,14 +139,14 @@ public async Task>> Metric(QueryType queryTy // This is to support SelectUnique which is the only query type with a list-type result. result = from r in reply.Value("result") let c = string.Join(",", r.Value("result").Values()) - let g = r.Value(groupby) + let g = r.Value(string.Join(",", groupby)) select new QueryGroupValue(c, g); } else { result = from r in reply.Value("result") let c = r.Value("result") - let g = r.Value(groupby) + let g = r.Value(string.Join(",", groupby)) select new QueryGroupValue(c, g); } return result; @@ -195,7 +195,7 @@ public async Task>> Metric(QueryType quer return result; } - public async Task>>>> Metric(QueryType queryType, string collection, string targetProperty, string groupby, QueryTimeframe timeframe, QueryInterval interval, IEnumerable filters = null, string timezone = "") + public async Task>>>> Metric(QueryType queryType, string collection, string targetProperty, IEnumerable groupby, QueryTimeframe timeframe, QueryInterval interval, IEnumerable filters = null, string timezone = "") { if (queryType == null) throw new ArgumentNullException("queryType"); @@ -207,13 +207,13 @@ public async Task(); parms.Add(KeenConstants.QueryParmEventCollection, collection); parms.Add(KeenConstants.QueryParmTargetProperty, targetProperty); - parms.Add(KeenConstants.QueryParmGroupBy, groupby); + parms.Add(KeenConstants.QueryParmGroupBy, string.Join(",", groupby)); parms.Add(KeenConstants.QueryParmTimeframe, timeframe.ToSafeString()); parms.Add(KeenConstants.QueryParmInterval, interval.ToSafeString()); parms.Add(KeenConstants.QueryParmTimezone, timezone); @@ -303,7 +303,7 @@ public async Task> MultiAnalysis(string collection, I return result; } - public async Task>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, IEnumerable filters = null, string groupby = "", string timezone = "") + public async Task>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, IEnumerable filters = null, IEnumerable groupby = null, string timezone = "") { var jObs = analysisParams.Select(x => new JProperty(x.Label, JObject.FromObject(new { analysis_type = x.Analysis, target_property = x.TargetProperty }))); @@ -314,7 +314,7 @@ public async Task>>> Mul parms.Add(KeenConstants.QueryParmTimeframe, timeframe.ToSafeString()); parms.Add(KeenConstants.QueryParmTimezone, timezone); parms.Add(KeenConstants.QueryParmFilters, filters == null ? "" : JArray.FromObject(filters).ToString()); - parms.Add(KeenConstants.QueryParmGroupBy, groupby); + parms.Add(KeenConstants.QueryParmGroupBy, groupby == null ? "" : string.Join(",", groupby)); parms.Add(KeenConstants.QueryParmAnalyses, parmsJson); var reply = await KeenWebApiRequest(KeenConstants.QueryMultiAnalysis, parms).ConfigureAwait(false); @@ -326,7 +326,7 @@ public async Task>>> Mul string grpVal = ""; foreach (JProperty p in i.Values()) { - if (p.Name == groupby) + if (groupby.Contains(p.Name)) grpVal = (string)p.Value; else d.Add(p.Name, (string)p.Value); @@ -368,7 +368,7 @@ public async Task>>> M return result; } - public async Task>>>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, string groupby = "", string timezone = "") + public async Task>>>>> MultiAnalysis(string collection, IEnumerable analysisParams, QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable filters = null, IEnumerable groupby = null, string timezone = "") { var jObs = analysisParams.Select(x => new JProperty(x.Label, JObject.FromObject(new { analysis_type = x.Analysis, target_property = x.TargetProperty }))); var parmsJson = JsonConvert.SerializeObject(new JObject(jObs), Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); @@ -378,7 +378,7 @@ public async Task()) { - if (p.Name == groupby) + if (groupby.Contains(p.Name)) grpVal = (string)p.Value; else d.Add(p.Name, (string)p.Value);