static void Main(string[] args) { //used v 2.4.3 of C# driver and v 3.4.1 of the db engine for this example var client = new MongoClient(); IMongoDatabase db = client.GetDatabase("agg_example"); var collectionName = "points"; db.DropCollection(collectionName); IMongoCollection<PlayerPoints> collection = db.GetCollection<PlayerPoints>(collectionName); IEnumerable<PlayerPoints> data = GetDummyData(); collection.InsertMany(data); //some seasons to filter by var seasons = new[] {6, 7}; //clear out unparticipating players from aggregated data to reduce computation overhead var seasonFilter = Builders<SeasonPoint>.Filter.In(season => season.Season, seasons); var playerFilter = Builders<PlayerPoints>.Filter.ElemMatch(point => point.SeasonalPoints, seasonFilter); //This shall remove all un-necessary seasons from aggregation pipeline var bsonFilter = new BsonDocument { new BsonElement("SeasonalPoints.Season", new BsonDocument("$in", new BsonArray(seasons))) }; var groupBy = new BsonDocument// think of this as a grouping with an anonyous object declaration { new BsonElement("_id", "$_id"),//This denotes the key by which to group - in this case the player's id new BsonElement("playerSum", new BsonDocument("$sum", "$SeasonalPoints.Point")),//We aggregate the player's points new BsonElement("player", new BsonDocument("$first", "$$CURRENT")),// preserve player reference for projection stage }; var sort = Builders<BsonDocument>.Sort.Descending(doc => doc["playerSum"]); List<BsonDocument> a = collection .Aggregate() .Match(playerFilter) .Unwind(x => x.SeasonalPoints)//this is where the magic happens .Match(bsonFilter) .Group(groupBy) .Sort(sort) .ToList();
static void Main(string[] args) { //used v 2.4.3 of C# driver and v 3.4.1 of the db engine for this example var client = new MongoClient(); IMongoDatabase db = client.GetDatabase("agg_example"); var collectionName = "points"; db.DropCollection(collectionName); IMongoCollection <BsonDocument> collection = db.GetCollection <BsonDocument>(collectionName); IEnumerable <BsonDocument> data = GetDummyData().Select(d => d.ToBsonDocument()); collection.InsertMany(data); //some seasons to filter by - note transformation to zero based var seasons = new[] { 6, 7 }; //This is the query body: var seasonIndex = seasons.Select(i => i - 1); //This shall remove all un-necessary seasons from aggregation pipeline var bsonFilter = new BsonDocument { new BsonElement("Season", new BsonDocument("$in", new BsonArray(seasonIndex))) }; var groupBy = new BsonDocument // think of this as a grouping with an anonyous object declaration { new BsonElement("_id", "$_id"), //This denotes the key by which to group - in this case the player's id new BsonElement("playerSum", new BsonDocument("$sum", "$SeasonalPoints")), //We aggregate the player's points new BsonElement("player", new BsonDocument("$first", "$$CURRENT")), // preserve player reference for projection stage }; var sort = Builders <BsonDocument> .Sort.Descending(doc => doc["playerSum"]); var unwindOptions = new AggregateUnwindOptions <BsonDocument> { IncludeArrayIndex = new StringFieldDefinition <BsonDocument>("Season") }; var projection = Builders <BsonDocument> .Projection.Expression((doc => doc["player"])); List <BsonValue> sorted = collection .Aggregate() .Unwind(x => x["SeasonalPoints"], unwindOptions) .Match(bsonFilter) .Group(groupBy) .Sort(sort) .Project(projection) .ToList(); }