namespace TestMongo
{
using System;
using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
public partial class Program
{
#region Public Methods and Operators
public static void DemoAggregation(MongoCollection<ClubMember> collection)
{
var sortFamiliesOperation = new BsonDocument { { "$sort", new BsonDocument { { "FamilyName", 1 } } } };
var groupFamiliesOperation = new BsonDocument
{
{
//Sort the documents into groups
"$group",
new BsonDocument
{
//Make the unique identifier for the group a BSON element consisting
// of a field named FamilyId.
// Set its value to that of the Lastname field
{
"_id",
new BsonDocument { { "FamilyId", "$Lastname" } }
},
{
//Declare another output field and name it Count.
//Increase Count's value by one for each document in the group
"Count", new BsonDocument { { "$sum", 1 } }
},
{
//Declare an other output field and name it TotalAge.
//Increase TotalAge's value by the Age value for each document in the group
"TotalAge",
new BsonDocument { { "$sum", "$Age" } }
},
{
"MinAge", new BsonDocument { { "$min", "$Age" } }
},
{
"MaxAge", new BsonDocument { { "$max", "$Age" } }
}
}
}
};
// Example of a document formed as a result of the group operation
//{ "_id" : { "Lastname" : "Thomas" }, "Count" : 6, "TotalAge" : 204, "MinAge" : 20, "MaxAge" : 48 }
var projectFamilyOperation = new BsonDocument
{
{
"$project", new BsonDocument
{
//Drop the _id field, the '0' means drop
{ "_id", 0 },
//Declare a new field. Set its value to the FamilyId value of the _id
{ "FamilyName", "$_id.FamilyId" },
//Keep the fields detailed below. The '1' means keep
{ "Count", 1 },
{ "TotalAge", 1 },
{ "MinAge", 1 },
{ "MaxAge", 1 }
}
}
};
AggregateResult familyAggregate = collection.Aggregate(
groupFamiliesOperation, projectFamilyOperation, sortFamiliesOperation);
IEnumerable<FamilyStat> familyStats =
familyAggregate.ResultDocuments.Select(BsonSerializer.Deserialize<FamilyStat>);
Console.WriteLine(
String.Format("{0,-12}{1,10}{2,12}{3,13}{4,12}", "Family", "Members", "Oldest", "Youngest", "TotalAge"));
foreach (FamilyStat stats in familyStats)
{
Console.WriteLine(
String.Format(
"{0,-11}{1,8}{2,12}{3,14}{4,14}",
stats.FamilyName,
stats.Count,
stats.MaxAge,
stats.MinAge,
stats.TotalAge));
}
DateTime utcTime5yearsago = DateTime.Now.AddYears(-5).ToUniversalTime();
var matchMembershipDateOperation = new BsonDocument
{
{ "$match", new BsonDocument { { "MembershipDate", new BsonDocument { { "$gte", utcTime5yearsago } } } } }
};
var unwindCarsOperation = new BsonDocument { { "$unwind", "$Cars" } };
var groupByCarTypeOperation = new BsonDocument
{
{
//Sort the documents into groups
"$group",
new BsonDocument
{
//Make the unique identifier for the group a BSON element consisting
// of a field named Car.
// Set its value to that of the Cars field
// The Cars field is nolonger an array because it has been unwound
{ "_id", new BsonDocument { { "Car", "$Cars" } } },
{
"Owners",
new BsonDocument
{
{
//add a value to the Owners Array if it does not
//already contain an identical value
"$addToSet",
//The value to add is a BsonDocument with an identical structure to
// a serialized ClubMember class.
new BsonDocument
{
{ "_id", "$_id" },
{ "Lastname", "$Lastname" },
{ "Forename", "$Forename" },
{ "Age", "$Age" },
{
"MembershipDate", "$MembershipDate"
}
}
}
}
}
}
}
};
var projectMakeOfCarOperation = new BsonDocument
{ { "$project", new BsonDocument { { "_id", 0 }, { "MakeOfCar", "$_id.Car" }, { "Owners", 1 } } } };
var sortCarsOperation = new BsonDocument { { "$sort", new BsonDocument { { "MakeOfCar", 1 } } } };
AggregateResult aggResult = collection.Aggregate(
matchMembershipDateOperation,
unwindCarsOperation,
groupByCarTypeOperation,
projectMakeOfCarOperation,
sortCarsOperation);
IEnumerable<CarStat> carStats = aggResult.ResultDocuments.Select(BsonSerializer.Deserialize<CarStat>);
foreach (CarStat stat in carStats)
{
Console.WriteLine("\n\rCar Marque : {0}\n\r", stat.MakeOfCar);
IEnumerable<ClubMember> clubMembers =
stat.Owners.AsEnumerable().Select(BsonSerializer.Deserialize<ClubMember>).OrderBy(p => p.Lastname).
ThenBy(p => p.Forename).ThenBy(p => p.Age).Select(p => p);
foreach (ClubMember member in clubMembers)
{
member.PrintDetailsToScreen();
}
}
}
#endregion
}
}