Skip to content

Instantly share code, notes, and snippets.

@peters
Last active October 2, 2017 15:58
Show Gist options
  • Save peters/66abc9be2f6334e9d68603697b29d74f to your computer and use it in GitHub Desktop.
Save peters/66abc9be2f6334e9d68603697b29d74f to your computer and use it in GitHub Desktop.
A collection of fluent aggregation extension methods that should find it's way into the official MongoDB c# driver

Spec

public static class FluentAggregationExtensions 
{

  public static Task<List<TNewResult>> ProjectToListAsync<TResult, TNewResult>(this IAggregateFluent<TResult> aggregate, Expression<Func<TResult, IEnumerable<TNewResult>>> field)
  {
    var fieldName = $"${((MemberExpression) field.Body).Member.Name}";

    return aggregate
        .AppendStage<BsonDocument>(new BsonDocument
        {
            { "$unwind", fieldName}
        })
        .AppendStage<BsonDocument>(new BsonDocument
        {
            {
                "$replaceRoot", new BsonDocument
                {
                    {"newRoot", fieldName}
                }
            }
        })
        .As<TNewResult>()
        .ToListAsync();
  }
  
}

Entities

class Animal
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
}

[CollectionName("animals")]
class AnimalsEntity
{
    [BsonId]
    public ObjectId Id { get; set; }
    public List<AnimalsEntity> Animals { get; set; }
}

Projections

Project only Id and Name for all animals of type Cat.

var animals = await Database
    .GetCollection<AnimalsEntity>()
    .Aggregate()
    .Match(x => x.Name.Contains("Cat"))
    .Project(x => new { Pets = x.Animals.Select(animal => new { _id = animal.Id, anmial.Name })})
    .ProjectToListAsync(x => x.Animals);
    
Debug.WriteLine($"You own {animals.Count} animals.");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment