7

I am trying to use the 2.2 version of the driver to create an aggregation query using the FilterDefintion for match phase and ProjectionDefinition for group phase. But I'm not quite sure how to create a ProjectionDefinition. The API is like:

 FilterDefinition<T> filter=Builders<T>.Filter.Eq("Foo","Bar");
 ProjectionDefinition<T> projection=...
 IAggregateFluent<T> aggr = fileCol.Aggregate<T>()
            .Match(filter)
            .Group(projection);

The match filter works just like in a normal Find. But I'm not sure how to create the projection.

I can create just a normal Bson document and put it in that phase, and it works. But I'm trying to create a consistent interface using the strongly-typed objects that come from builders, and this is the one place where I can't figure out how to do that. I would think it is possible since the API exists.

(The Bson document for the group phase can be made like):

projection = new BsonDocument("_id","$SomeIdField").
    Add("Result",new BsonDocument("$max","$someNumberField"));

EDIT: The MongoDB API I am referring to is linked below, and I quoted the relevant section. There are no examples provided. I agree that a 'GroupDefinition' would have made more sense, but I didn't write it :-) And by strongly typed, I mean typed with the return value of whatever is, not BsonDocument.

http://api.mongodb.com/csharp/current/html/M_MongoDB_Driver_AggregateFluentBase_1_Group__1.htm

Blockquote

public abstract IAggregateFluent<TNewResult> Group<TNewResult>(
    ProjectionDefinition<TResult, TNewResult> group

)

Parameters

group Type: MongoDB.Driver.ProjectionDefinition<TResult, TNewResult>

The group projection.

Type Parameters

TNewResult

The type of the result of the stage.

Blockquote

2
  • ProjectionDefinition in the grouping stage ?? that doesn't sound right. Its a stage on its own just like match. btw BsonDocument are strongly typed. If its just a key value pair the BsonDocument is your object and I think for the accumulator operators you already have the wrappers that you can use. Commented Dec 21, 2016 at 22:51
  • @SagarReddy, I agree that it is confusing, but that is how the mdb docs have it. I have linked the relevant section in the question. Commented Dec 21, 2016 at 23:22

1 Answer 1

20

There are some great examples on AggregateGroupTranslatorTests.cs, which is the test file for the MongoDB .NET Driver: aggregation group.

For example, if you have this class definition:

public class ExampleGroup 
{
    [BsonId]
    public ObjectId Id {get;set;}
    public string SomeStringField { get; set; }
    public int SomeNumberField {get; set;}
}

And you would like to perform grouping of

{ _id: "$SomeStringField", Result: { "$max": "$SomeNumberField" } }

You could execute as below:

var result = collection.Aggregate()
                        .Group(
                            x => x.SomeStringField,
                            g => new {
                                  Result = g.Select(
                                           x => x.SomeNumberField
                                           ).Max()
                            }
                        ).ToList();
result.ForEach(doc => Console.WriteLine(doc.ToJson()));

The above snippet was tested on .Net 4.5, MongoDB 3.4 and MongoDB .Net/C# Driver v2.3. I know you're using v2.2, but there's no (or any) changes for the project definition grouping.

Also check out other LINQ translator tests MongoDB.Driver.Tests/Linq/Translators

Sign up to request clarification or add additional context in comments.

1 Comment

I missed that this question was answered, sorry for the late acceptance. I'd prefer not to use LINQ but I didn't say that in the original post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.