public void TestAggregationBuilder() { Assert.Equal("*", new AggregationBuilder().GetArgsString()); AggregationBuilder r1 = new AggregationBuilder() .GroupBy("@actor", Count().As("cnt")) .SortBy(Descending("@cnt")); Assert.Equal("* GROUPBY 1 @actor REDUCE COUNT 0 AS cnt SORTBY 2 @cnt DESC", r1.GetArgsString()); Group group = new Group("@brand") .Reduce(Quantile("@price", 0.50).As("q50")) .Reduce(Quantile("@price", 0.90).As("q90")) .Reduce(Quantile("@price", 0.95).As("q95")) .Reduce(Avg("@price")) .Reduce(Count().As("count")); AggregationBuilder r2 = new AggregationBuilder() .GroupBy(group) .Limit(10) .SortByDescending("@count"); Assert.Equal("* GROUPBY 1 @brand REDUCE QUANTILE 2 @price 0.5 AS q50 REDUCE QUANTILE 2 @price 0.9 AS q90 REDUCE QUANTILE 2 @price 0.95 AS q95 REDUCE AVG 1 @price REDUCE COUNT 0 AS count LIMIT 0 10 SORTBY 2 @count DESC", r2.GetArgsString()); AggregationBuilder r3 = new AggregationBuilder() .Load("@count") .Apply("@count%1000", "thousands") .SortBy(Descending("@count")) .Limit(0, 2); Assert.Equal("* LOAD 1 @count APPLY @count%1000 AS thousands SORTBY 2 @count DESC LIMIT 0 2", r3.GetArgsString()); }
public IEnumerable <Tuple <DateTime, Int32> > WinsGraph(IFilterBuilder userFilter, IFilterBuilder prizeFilter, bool byDay) { IMongoQuery query = null; if (userFilter != null) { query = new MongoFilterVisitor(userFilter.Build()).Build(); } var queryPrize = Query.And(Query.Exists("Prizes._v"), Query.Not(Query.Size("Prizes._v", 0)), Query.NE("Hidden", true)); if (query != null) { query = Query.And(queryPrize, query); } var aggQuery = new AggregationBuilder("User") .Match(query) .Project(new Dictionary <String, object> { { "Prizes._v", 1 } }) .Unwind("$Prizes._v") .Match(new MongoFilterVisitor(prizeFilter.Build()).Build()) .Project(winGraphProjection) .Group(byDay ? byDayGroup : byMinuteGroup); var im = AggregationResultToList(RunAggreation(aggQuery.Pipeline)); return(byDay ? GraphByDays(im) : GraphByMinutes(im)); }
public IEnumerable <Object> RegistrationReport(IFilterBuilder userFilter, ISort sort, int skip, int limit) { IMongoQuery query = null; if (userFilter != null) { query = new MongoFilterVisitor(userFilter.Build()).Build(); } //var aggQuery = new AggregationBuilder("UserXUserEvent") // .Match(query) // .Project(registrationReportFields) // .Unwind("$UserEvents") // .Sort(sort) // .Skip(skip) // .Limit(limit).Pipeline; var aggQuery = new AggregationBuilder("User") .Match(query) .Project(registrationReportFields) .Sort(sort) .Skip(skip) .Limit(limit).Pipeline; // Debug.WriteLine(aggQuery); //return RunCommand(aggQuery); return(AggregationResultToList(RunAggreation(aggQuery))); }
//private MongoCursor<UserEvent> GetEventsCursor(ObjectId campaignId, // IEnumerable<EventTypeEnum> eventTypes, DateTime? start, DateTime? end) //{ // var query = Query.And(Query.EQ("CampaignId", campaignId), // Query.In("EventTypeId", eventTypes.Select(x => BsonValue.Create((int)x)))); // if (start.HasValue) // query = Query.And(query, Query.GTE("EventDate", start.Value.ToUniversalTime().Ticks)); // if (end.HasValue) // query = Query.And(query, Query.LTE("EventDate", end.Value.ToUniversalTime().Ticks)); // query = Query.And(query, Query.NE("Hidden", true)); // return Context..SlaveServerCollection.FindAs<UserEvent>(query); //} public IEnumerable <Object> WinsReport(IFilterBuilder userFilter, IFilterBuilder prizeFilter, ISort sort, int skip, int limit) { IMongoQuery query = null; if (userFilter != null) { query = new MongoFilterVisitor(userFilter.Build()).Build(); } var queryPrize = Query.And(Query.Exists("Prizes._v"), Query.Not(Query.Size("Prizes._v", 0)), Query.NE("Hidden", true)); if (query != null) { query = Query.And(queryPrize, query); } else { query = queryPrize; } var aggQuery = new AggregationBuilder("User") .Match(query) .Project(winReportFields) .Unwind("$Prizes._v") .Match(new MongoFilterVisitor(prizeFilter.Build()).Build()) .Sort(sort) .Skip(skip) .Limit(limit).Pipeline; //Console.WriteLine(aggQuery.ToString()); return(AggregationResultToList(RunAggreation(aggQuery))); }
public void ShouldNotAddNyNameAggregationForEmptyRequest() { var req = new NameValueCollection(); var builder = new AggregationBuilder(req); builder.MaybeAddByNameAggregation("test"); Assert.AreEqual(0, builder.ToList().Count); }
protected override IEnumerable <ICategoryFunction> DetermineAggregations(System.Collections.Specialized.NameValueCollection requestParams) { var builder = new AggregationBuilder(requestParams); builder.MaybeAddDateAggregation("bizDate"); builder.MaybeAddByNameAggregation("bookId"); return(builder.ToList()); }
public void ShouldAddDateAggregationWhenParameterIsAvailable() { var req = new NameValueCollection(); req.Add("bizDate-granularity", "monthly"); var builder = new AggregationBuilder(req); builder.MaybeAddDateAggregation("bizDate"); Assert.AreEqual(1, builder.ToList().Count); Assert.That(builder.ToList()[0], Is.InstanceOf(typeof(DateCategoryFunction))); }
public void ShouldAddIntegerAggregationWhenParameterIsAvailable() { var req = new NameValueCollection { { "someInt-granularity", "100s" } }; var builder = new AggregationBuilder(req); builder.MaybeAddIntegerAggregation("someInt"); Assert.AreEqual(1, builder.ToList().Count); Assert.That(builder.ToList()[0], Is.InstanceOf(typeof(IntegerCategoryFunction))); Assert.AreEqual(100, ((IntegerCategoryFunction)builder.ToList()[0]).Denominator); }
public void ShouldAddPrefixAggregationWhenParameterIsAvailable() { var req = new NameValueCollection { { "someString-length", "5" } }; var builder = new AggregationBuilder(req); builder.MaybeAddPrefixAggregation("someString"); Assert.AreEqual(1, builder.ToList().Count); Assert.That(builder.ToList()[0], Is.InstanceOf(typeof(PrefixCategoryFunction))); Assert.AreEqual(5, ((PrefixCategoryFunction)builder.ToList()[0]).Length); }
public void ShouldNotAddDateAggregationWhenDifferentParameterIsAvailable() { var req = new NameValueCollection(); req.Add("someString-granularity", "prefix(1)"); var builder = new AggregationBuilder(req); builder.MaybeAddDateAggregation("bizDate"); Assert.AreEqual(0, builder.ToList().Count); }
public void ShouldAddByNameAggregationWhenParameterIsAvailable() { var req = new NameValueCollection(); req.Add("someString-granularity", "by-name"); var builder = new AggregationBuilder(req); builder.MaybeAddByNameAggregation("someString"); Assert.AreEqual(1, builder.ToList().Count); Assert.That(builder.ToList()[0], Is.InstanceOf(typeof(ByNameCategoryFunction))); }
public IEnumerable <Object> WinnersReport(IFilterBuilder userFilter, IFilterBuilder prizeFilter, ISort sort, int skip, int limit) /** * > db.User.aggregate( * {$match: { CampaignId: ObjectId("5011b6099610f710f4fd438e"), PrizeCount: {$gt:3}}}, # user fields * {$project: { LastName: 1, Prizes:1} } # return fields and Prizes * {$unwind: '$Prizes._v'}, # unwind the prizes * {$match: {"Prizes._v.PrizeDate": {$gte: NumberLong("634794549227340147"), $lte: NumberLong("634794559975708161")}}} * # match on prizes * {$group: { _id: { _id: '$_id', LastName: '$LastName' ....}, # re-group all the fields you want to see except... * "Prizes" : { $addToSet: '$Prizes._v'}}}, # prizes, which you add to set (and now they are unsorted!) * {$project: { _id: "$_id._id", LastName:"$_id.LastName", Prizes: 1}}) # project out of _id to get to top level */ { IMongoQuery userQuery = null; if (userFilter != null) { userQuery = new MongoFilterVisitor(userFilter.Build()).Build(); } var queryPrize = Query.And(Query.Exists("Prizes._v"), Query.Not(Query.Size("Prizes._v", 0)), Query.NE("Hidden", true)); userQuery = userQuery != null?Query.And(queryPrize, userQuery) : queryPrize; IMongoQuery prizeQuery = new MongoFilterVisitor(prizeFilter.Build()).Build(); var groupFields = winnersReportFields.Keys.Where(x => !x.StartsWith("Prizes")).ToList(); var id = FieldDocument("$", groupFields); var finalProject = FieldDocument("$_id.", groupFields).Add("Prizes", 1); var group = new BsonDocument { { "_id", id }, { "Prizes", new BsonDocument("$addToSet", "$Prizes._v") } }; var aggQuery = new AggregationBuilder("User") .Match(userQuery) .Project(winnersReportFields) .Unwind("$Prizes._v") .Match(prizeQuery) .Group(group) .Project(finalProject) .Sort(sort) .Skip(skip) .Limit(limit).Pipeline; //Console.WriteLine(aggQuery.ToString()); return(AggregationResultToList(RunAggreation(aggQuery))); }
public void TestApplyAndFilterAggregations() { /** * 127.0.0.1:6379> FT.CREATE test_index SCHEMA name TEXT SORTABLE subj1 NUMERIC SORTABLE subj2 NUMERIC SORTABLE * OK * 127.0.0.1:6379> FT.ADD test_index data1 1.0 FIELDS name abc subj1 20 subj2 70 * OK * 127.0.0.1:6379> FT.ADD test_index data2 1.0 FIELDS name def subj1 60 subj2 40 * OK * 127.0.0.1:6379> FT.ADD test_index data3 1.0 FIELDS name ghi subj1 50 subj2 80 * OK * 127.0.0.1:6379> FT.ADD test_index data1 1.0 FIELDS name abc subj1 30 subj2 20 * OK * 127.0.0.1:6379> FT.ADD test_index data2 1.0 FIELDS name def subj1 65 subj2 45 * OK * 127.0.0.1:6379> FT.ADD test_index data3 1.0 FIELDS name ghi subj1 70 subj2 70 * OK */ Client cl = GetClient(); Schema sc = new Schema(); sc.AddSortableTextField("name", 1.0); sc.AddSortableNumericField("subj1"); sc.AddSortableNumericField("subj2"); cl.CreateIndex(sc, new ConfiguredIndexOptions()); cl.AddDocument(new Document("data1").Set("name", "abc").Set("subj1", 20).Set("subj2", 70)); cl.AddDocument(new Document("data2").Set("name", "def").Set("subj1", 60).Set("subj2", 40)); cl.AddDocument(new Document("data3").Set("name", "ghi").Set("subj1", 50).Set("subj2", 80)); cl.AddDocument(new Document("data4").Set("name", "abc").Set("subj1", 30).Set("subj2", 20)); cl.AddDocument(new Document("data5").Set("name", "def").Set("subj1", 65).Set("subj2", 45)); cl.AddDocument(new Document("data6").Set("name", "ghi").Set("subj1", 70).Set("subj2", 70)); AggregationBuilder r = new AggregationBuilder().Apply("(@subj1+@subj2)/2", "attemptavg") .GroupBy("@name", Reducers.Avg("@attemptavg").As("avgscore")) .Filter("@avgscore>=50") .SortBy(10, SortedField.Ascending("@name")); // actual search AggregationResult res = cl.Aggregate(r); Row?r1 = res.GetRow(0); Assert.NotNull(r1); Assert.Equal("def", r1.Value.GetString("name")); Assert.Equal(52.5, r1.Value.GetDouble("avgscore")); Row?r2 = res.GetRow(1); Assert.NotNull(r2); Assert.Equal("ghi", r2.Value.GetString("name")); Assert.Equal(67.5, r2.Value.GetDouble("avgscore")); }
public void ShouldInvalidGranularityExceptionWhenGranularityValueIsBad() { var req = new NameValueCollection(); req.Add("bizDate-granularity", "invalid"); var builder = new AggregationBuilder(req); try { builder.MaybeAddDateAggregation("bizDate"); Assert.Fail("Should have thrown InvalidGranularityException"); } catch (InvalidGranularityException ex) { Assert.AreEqual("The aggregation value 'invalid' is not valid for the field 'bizDate'", ex.Message); } }
public void ShouldThrowInvalidGranularityExceptionWhenBadNumberedIntegerGranularityIsGiven() { var req = new NameValueCollection { { "someInt-granularity", "10a0s" } }; var builder = new AggregationBuilder(req); try { builder.MaybeAddIntegerAggregation("someInt"); Assert.Fail("Should have thrown InvalidGranularityException"); } catch (InvalidGranularityException ex) { Assert.AreEqual("The aggregation value '10a0s' is not valid for the field 'someInt'", ex.Message); } }
public void ShouldThrowInvalidGranularityExceptionWhenPrefixLengthIsntANumber() { var req = new NameValueCollection { { "someString-length", "blah" } }; var builder = new AggregationBuilder(req); try { builder.MaybeAddPrefixAggregation("someString"); Assert.Fail("Should have thrown InvalidGranularityException"); } catch (InvalidGranularityException ex) { Assert.AreEqual("The aggregation value 'blah' is not valid for the field 'someString'", ex.Message); } }
public static bool IsAggregate(this MethodCallExpression methodCall, MappingSchema mapping) { if (methodCall.IsQueryable(AggregationBuilder.MethodNames)) { return(true); } if (methodCall.Arguments.Count > 0) { var function = AggregationBuilder.GetAggregateDefinition(methodCall, mapping); return(function != null); } return(false); }
private static async Task <List <T> > ToListWithMultipleSortAsync <T>(this Client client, string whereQuery, int skip, int take, List <RedisearchSortDescriptor> sorts) where T : class, new() { PropertyInfo[] props = Helpers.GetModelProperties <T>().Where(x => x.GetSetMethod() != null).ToArray(); SortedField[] sort = sorts.Select(x => new SortedField($"@{x.PropertyName}", x.Ascending ? Order.Ascending : Order.Descending)) .ToArray(); string[] returnFields = props.Select(x => x.Name).ToArray(); AggregationBuilder aggregation = new AggregationBuilder(whereQuery).Load(returnFields) .SortBy(sort) .Limit(skip, take); AggregationResult aggreagate = await client.AggregateAsync(aggregation); IReadOnlyList <Dictionary <string, RedisValue> > aggregationResult = aggreagate.GetResults(); return(aggregationResult.Select(x => SerializeProperties <T>(props, x.ToList())) .ToList()); }
public IEnumerable <Object> SpinReport(IFilterBuilder userFilter, IFilterBuilder eventFilter, ISort sort, int skip, int limit) { IMongoQuery query = new MongoFilterVisitor(userFilter.Build()).Build(); IMongoQuery eventQuery = new MongoFilterVisitor(eventFilter.Build()).Build(); var aggQuery = new AggregationBuilder("UserXUserEvent") .Match(query) .Project(registrationReportFields) .Unwind("UserEvents") .Match(eventQuery) .Sort(sort) .Skip(skip) .Limit(limit) .Pipeline; return(AggregationResultToList(RunAggreation(aggQuery))); }
public void TestAggregations() { /** * 127.0.0.1:6379> FT.CREATE test_index SCHEMA name TEXT SORTABLE count NUMERIC SORTABLE * OK * 127.0.0.1:6379> FT.ADD test_index data1 1.0 FIELDS name abc count 10 * OK * 127.0.0.1:6379> FT.ADD test_index data2 1.0 FIELDS name def count 5 * OK * 127.0.0.1:6379> FT.ADD test_index data3 1.0 FIELDS name def count 25 */ Client cl = GetClient(); Schema sc = new Schema(); sc.AddSortableTextField("name", 1.0); sc.AddSortableNumericField("count"); cl.CreateIndex(sc, new ConfiguredIndexOptions()); cl.AddDocument(new Document("data1").Set("name", "abc").Set("count", 10)); cl.AddDocument(new Document("data2").Set("name", "def").Set("count", 5)); cl.AddDocument(new Document("data3").Set("name", "def").Set("count", 25)); AggregationBuilder r = new AggregationBuilder() .GroupBy("@name", Reducers.Sum("@count").As("sum")) .SortBy(10, SortedField.Descending("@sum")); // actual search AggregationResult res = cl.Aggregate(r); Row?r1 = res.GetRow(0); Assert.NotNull(r1); Assert.Equal("def", r1.Value.GetString("name")); Assert.Equal(30, r1.Value.GetInt64("sum")); Assert.Equal(30.0, r1.Value.GetDouble("sum")); Assert.Equal(0L, r1.Value.GetInt64("nosuchcol")); Assert.Equal(0.0, r1.Value.GetDouble("nosuchcol")); Assert.Null(r1.Value.GetString("nosuchcol")); Row?r2 = res.GetRow(1); Assert.NotNull(r2); Assert.Equal("abc", r2.Value.GetString("name")); Assert.Equal(10L, r2.Value.GetInt64("sum")); }
public IEnumerable <Object> PrizesReport(IFilterBuilder userFilter, ISort sort, int skip, int limit) { IMongoQuery query = null; if (userFilter != null) { query = new MongoFilterVisitor(userFilter.Build()).Build(); } var aggQuery = new AggregationBuilder("Prize") .Match(query) .Project(prizeReportFields) .Sort(sort) .Skip(skip) .Limit(limit).Pipeline; //Console.WriteLine(aggQuery.ToString()); return(RunAggreationToList <Prize>(aggQuery)); }
public IEnumerable <Tuple <DateTime, Int32> > RegistrationGraph(IFilterBuilder userFilter, bool byDay) { IMongoQuery query = null; if (userFilter != null) { query = new MongoFilterVisitor(userFilter.Build()).Build(); } var aggQuery = new AggregationBuilder("User") .Match(query) .Project(registrationGraphProjection) .Group(byDay ? byDayGroup : byMinuteGroup); var im = AggregationResultToList(RunAggreation(aggQuery.Pipeline)); return(byDay ? GraphByDays(im) : GraphByMinutes(im)); }
protected AggregationBuilder WinsGraphBase(IFilterBuilder userFilter, IFilterBuilder prizeFilter) { var baseQuery = Query.And( Query.Exists("Prizes._v"), Query.Not(Query.Size("Prizes._v", 0)), Query.NE("Hidden", true)); var userQuery = new MongoFilterVisitor(baseQuery, userFilter.Build()).Build(); var prizeQuery = new MongoFilterVisitor(prizeFilter.Build()).Build(); var aggBuilder = new AggregationBuilder("User") .Match(userQuery) .Project(new Dictionary <string, object> { { "CampaignId", 1 }, { "Prizes", 1 } }) .Unwind("$Prizes._v") .Match(prizeQuery); return(aggBuilder); }
public void TestGetTagFieldUnf() { // Add version check Client cl = GetClient(); // Check that UNF can't be given to non-sortable filed try { var temp = new Schema().AddField(new TextField("non-sortable-unf", 1.0, sortable: false, unNormalizedForm: true)); Assert.True(false); } catch (ArgumentException) { Assert.True(true); } Schema sc = new Schema().AddSortableTextField("txt").AddSortableTextField("txt_unf", unf: true). AddSortableTagField("tag").AddSortableTagField("tag_unf", unNormalizedForm: true); Assert.True(cl.CreateIndex(sc, new ConfiguredIndexOptions())); Db.Execute("HSET", "doc1", "txt", "FOO", "txt_unf", "FOO", "tag", "FOO", "tag_unf", "FOO"); AggregationBuilder r = new AggregationBuilder() .GroupBy(new List <string> { "@txt", "@txt_unf", "@tag", "@tag_unf" }, new List <Aggregation.Reducers.Reducer> { }); AggregationResult res = cl.Aggregate(r); var results = res.GetResults()[0]; Assert.NotNull(results); Assert.Equal(4, results.Count); Assert.Equal("foo", results["txt"]); Assert.Equal("FOO", results["txt_unf"]); Assert.Equal("foo", results["tag"]); Assert.Equal("FOO", results["tag_unf"]); }
protected override IEnumerable<ICategoryFunction> DetermineAggregations(System.Collections.Specialized.NameValueCollection requestParams) { var builder = new AggregationBuilder(requestParams); builder.MaybeAddDateAggregation("bizDate"); builder.MaybeAddByNameAggregation("bookId"); return builder.ToList(); }
public void ShouldNotAddDateAggregationForEmptyRequest() { var req = new NameValueCollection(); var builder = new AggregationBuilder(req); builder.MaybeAddDateAggregation("test"); Assert.AreEqual(0, builder.ToList().Count); }
public async Task TestCursor() { /* * 127.0.0.1:6379> FT.CREATE test_index SCHEMA name TEXT SORTABLE count NUMERIC SORTABLE * OK * 127.0.0.1:6379> FT.ADD test_index data1 1.0 FIELDS name abc count 10 * OK * 127.0.0.1:6379> FT.ADD test_index data2 1.0 FIELDS name def count 5 * OK * 127.0.0.1:6379> FT.ADD test_index data3 1.0 FIELDS name def count 25 */ Client cl = GetClient(); Schema sc = new Schema(); sc.AddSortableTextField("name", 1.0); sc.AddSortableNumericField("count"); cl.CreateIndex(sc, new ConfiguredIndexOptions()); cl.AddDocument(new Document("data1").Set("name", "abc").Set("count", 10)); cl.AddDocument(new Document("data2").Set("name", "def").Set("count", 5)); cl.AddDocument(new Document("data3").Set("name", "def").Set("count", 25)); AggregationBuilder r = new AggregationBuilder() .GroupBy("@name", Reducers.Sum("@count").As("sum")) .SortBy(10, SortedField.Descending("@sum")) .Cursor(1, 3000); // actual search AggregationResult res = cl.Aggregate(r); Row?row = res.GetRow(0); Assert.NotNull(row); Assert.Equal("def", row.Value.GetString("name")); Assert.Equal(30, row.Value.GetInt64("sum")); Assert.Equal(30.0, row.Value.GetDouble("sum")); Assert.Equal(0L, row.Value.GetInt64("nosuchcol")); Assert.Equal(0.0, row.Value.GetDouble("nosuchcol")); Assert.Null(row.Value.GetString("nosuchcol")); res = cl.CursorRead(res.CursorId, 1); Row?row2 = res.GetRow(0); Assert.NotNull(row2); Assert.Equal("abc", row2.Value.GetString("name")); Assert.Equal(10, row2.Value.GetInt64("sum")); Assert.True(cl.CursorDelete(res.CursorId)); try { cl.CursorRead(res.CursorId, 1); Assert.True(false); } catch (RedisException) { } _ = new AggregationBuilder() .GroupBy("@name", Reducers.Sum("@count").As("sum")) .SortBy(10, SortedField.Descending("@sum")) .Cursor(1, 1000); await Task.Delay(1000).ForAwait(); try { cl.CursorRead(res.CursorId, 1); Assert.True(false); } catch (RedisException) { } }
public void ShouldThrowInvalidGranularityExceptionWhenCompletelyInvalidIntegerGranularityIsGiven() { var req = new NameValueCollection { { "someInt-granularity", "blah" } }; var builder = new AggregationBuilder(req); try { builder.MaybeAddIntegerAggregation("someInt"); Assert.Fail("Should have thrown InvalidGranularityException"); } catch (InvalidGranularityException ex) { Assert.AreEqual("The aggregation value 'blah' is not valid for the field 'someInt'", ex.Message); } }