14

I'm having some trouble with the new C# 2.0 MongoDB driver and the aggregation pipeline.

Basically, I'm trying to return the most popular elements within an array field on the object. The field type is: IList<string> FavouritePlaceIds { get; set; }.

I have the following MongoDB aggregation which is working as expected:

db.users.aggregate([
    { $unwind : "$FavouritePlaceIds" },
    { $group: { "_id": "$FavouritePlaceIds", "count": {$sum: 1}}}, 
    { $sort : { "count": -1 }}
])

However, the issue is now trying to translate that into C# code using the new MongoDB driver 2.0. I've been using the following link for help with the aggregation pipeline: http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/crud/reading/#unwind

I've got the following so far for my aggregation pipeline:

var pipeline = usersCollection.Aggregate()
                .Unwind(i => i.FavouritePlaceIds)
                .Group(i => i.FavouritePlaceIds, g => new { FavouritePlaceIds = g.Key, Count = g.Count() })
                .SortByDescending(i => i.Count);

When I go to compile that code, I get following message:

'BsonDocument' does not contain a definition for 'FavouritePlaceIds' and no extension method 'FavouritePlaceIds' accepting a first argument of type 'BsonDocument' could be found...

The error is occuring on the first parameter (i => i.FavouritePlaceIds) of the Group() method.

Reading the notes at the link provided under the group section, it mentions that:

Because $unwind is a type of projection, you must provide a return type.

So, I'm assuming that I'm not specifying a correct return type, which is why it's expecting a BsonDocument object, and failing to compile.

So, how can I specify the correct return type to use in the Group method?

Juzzbott
  • 1,737
  • 2
  • 25
  • 44

1 Answers1

11

When you let Unwind infer the type parameters it will use the collection type for TResult and BsonDocument for TNewResult.

If you want to use a specific type and not BsonDocument you need to add these type parameters:

var pipeline = usersCollection.Aggregate()
    .Unwind<OriginalType, NewResultType>(....

As always, you need to make sure the operation actually returns something that can be of that type.

i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • So do I need to set the OriginalType and NewResultType to the class the field is a member of, or the type of the field? – Juzzbott May 26 '15 at 07:39
  • @Juzzbott definitely not that type of the field. The `OrignalType` should be the collection type. The `NewResultType` should be the type of the projection being created in `Unwind`. It should probably work with the same original type. – i3arnon May 26 '15 at 07:42
  • Class `ApplicationUser` has the FavouritePlaceIds field. The following will now compile, but I'm getting a different error: `.Unwind(i => i.FavouritePlaceIds)`. Error message is: Cannot deserialize a 'List' from BsonType 'String'. – Juzzbott May 26 '15 at 07:43
  • @Juzzbott So it doesn't work. When you unwind the list you get back a single item and not a list so the deserialization fails. You can either use a different type, or make the serialization work with a single item. – i3arnon May 26 '15 at 07:44
  • So when I run the following, without the Group and Sort clauses, I get a collection of 3 BsonDocument objects: `var pipeline = usersCollection.Aggregate().Unwind(i => i.FavouritePlaceIds);` Is there a way to get the Unwind method to return a collection of ApplicationUser objects, so that the .Group method can work? The BsonDocument obejcts contain all the values for an ApplicationUser object. Alternatively, is there a way in the .Group method to specify the "FavouritePlaceIds" as a string instead of expression? – Juzzbott May 26 '15 at 07:53
  • @Juzzbott The contain the values, but not in the right configuration. These documents have a single string for `FavouritePlaceIds` instead of a list. So the serialization fails. – i3arnon May 26 '15 at 08:03
  • @Juzzbott I haven't seen a string, but you can use the projection builder: `Builders.Projection.*` – i3arnon May 26 '15 at 08:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/78761/discussion-between-juzzbott-and-i3arnon). – Juzzbott May 26 '15 at 08:16
  • hello from 2018, same problem here. @Juzzbott I curse you – R01010010 Sep 12 '18 at 15:11
  • @i3arnon I'm getting issues using aggregations and typings on my question, would be very grateful if you could take a look: https://stackoverflow.com/questions/57584337 – gdp Aug 21 '19 at 10:30