public async Task <List <GroupResult> > AggregateCountAsync(string author, GroupTimeRange groupTimeRange, FilterSettings filterSettings) { /* * { "$match" : { "Author" : "test" } }, * { "$group" : { "_id" : { "$dateToString" : { "format" : "%Y-%m-%d", "date" : "$Created", "timezone" : "Europe/Berlin" } }, "count" : { "$sum" : 1 } } }, * { "$project" : { "_id" : 0, "Key" : "$_id", "Value" : "$count" } }, * { "$sort" : { "Key" : 1 } } */ var projectStage = new BsonDocument { { "_id", 0 }, { "Key", "$_id" }, { "Value", "$count" } }; var watch = Stopwatch.StartNew(); var aggregateResult = this.documentCollection.Aggregate() .Match(this.BuildMatchStage(author, filterSettings)) .Group(MongoOp.GroupByDate("$Created", groupTimeRange, MongoOp.Count("count"))) .Project(projectStage) .Sort(MongoOp.SortBy("Key", asc: true)); var bsonResult = await aggregateResult.ToListAsync(); var result = bsonResult.Select(doc => BsonSerializer.Deserialize <GroupResult>(doc)) .ToList(); watch.Stop(); if (this.logger.IsEnabled(LogLevel.Debug)) { this.logger.LogDebug("Explore took {ms}ms.", watch.ElapsedMilliseconds); } return(result); }
private FilterDefinition <Document> BuildMatchStage(string author, FilterSettings filterSettings) { var filterList = new List <FilterDefinition <Document> >(); filterList.Add(this.filterBuilder.Where(d => d.Author == author)); if (filterSettings.Tags.Any()) { filterList.Add(this.filterBuilder.All(doc => doc.Tags, filterSettings.Tags)); } if (filterSettings.Values.Any()) { var valueFilter = filterSettings.Values.Select(v => MongoOp.Exists($"Values.{v}")); filterList.Add(new BsonDocument() { { "$or", new BsonArray(valueFilter) } }); } var matchStage = this.filterBuilder.And(filterList); return(matchStage); }
public async Task <List <ValuesResult> > AggregateValuesAsync(string author, GroupTimeRange groupTimeRange, Aggregate aggregation, FilterSettings filterSettings) { /* * db.getCollection('documents').aggregate([ * { "$match" : { "Author" : "test" } }, * { "$project" : { "date" : { "$dateToString" : { "format" : "%Y-%m-%d", "date" : "$Created", "timezone" : "Europe/Berlin" } }, "values" : { "$objectToArray" : "$Values" } } }, * { "$unwind" : "$values" }, * { "$group" : { "_id" : { "date" : "$date", "key" : "$values.k" }, "value" : { "$sum" : "$values.v" } } }, * { "$group" : { "_id" : "$_id.key", "values" : { "$push" : { "$arrayToObject" : [[{ "k" : "$_id.date", "v" : "$value" }]] } } } }, * { "$project": { "key": "$_id", "values": 1, "_id": 0 } } * ]) * */ var projectStage = new BsonDocument { { "date", MongoOp.DateToString("Created", groupTimeRange) }, { "values", new BsonDocument { { "$objectToArray", "$Values" } } } }; var aggregationOp = aggregation switch { Aggregate.Sum => "$sum", Aggregate.Average => "$avg", _ => throw new InvalidOperationException($"{aggregation} not supported") }; var groupByDateAndKey = new BsonDocument { { "_id", new BsonDocument { { "date", "$date" }, { "key", "$values.k" } } }, { "value", new BsonDocument { { aggregationOp, "$values.v" } } } }; var groupByDateOnly = new BsonDocument { { "_id", "$_id.key" }, { "Values", new BsonDocument { { "$push", new BsonDocument { { "$arrayToObject", new BsonArray { new BsonArray { new BsonDocument { { "k", "$_id.date" }, { "v", "$value" } } } } } } } } } }; var jssson = groupByDateOnly.ToJson(); var endProjectStage = new BsonDocument { { "Key", "$_id" }, { "Values", 1 }, { "_id", 0 }, }; var watch = Stopwatch.StartNew(); var aggregateResult = this.documentCollection.Aggregate() .Match(this.BuildMatchStage(author, filterSettings)) .Project(projectStage) .Unwind("values") .Group(groupByDateAndKey) .Group(groupByDateOnly) .Project(endProjectStage); var bsonResult = await aggregateResult.ToListAsync(); var result = bsonResult.Select(doc => BsonSerializer.Deserialize <ValuesResult>(doc)) .ToList(); watch.Stop(); if (this.logger.IsEnabled(LogLevel.Debug)) { this.logger.LogDebug("Explore took {ms}ms.", watch.ElapsedMilliseconds); } return(result); }