craiggwilson / fluent-mongo

Provides a fluent interface on top of the 10gen driver including Linq.
172 stars 28 forks source link

GroupBy does not work #31

Open ccm682 opened 13 years ago

ccm682 commented 13 years ago

Given:

        var datacoll = db.GetCollection<SensorData>("SensorData");
        var groups = datacoll.AsQueryable().GroupBy(x => x.PacketCounter);

where PacketCounter is an integer. Produces the following error:

Expression of type 'System.Collections.Generic.IEnumerable1[MongoDB.Bson.BsonDocument]' cannot be used for constructor parameter of type 'System.Collections.Generic.IEnumerable1[Masitek.Acquisition.ReadModel.SensorData]'

craiggwilson commented 13 years ago

Could you try adding a select statement to this, even if it seems stupid...

Just an FYI, underneath, this is the most complicated thing we do because this turns into a map reduce call. In terms of mongodb, this is expensive as well and shouldn't be used in real-time queries.

ccm682 commented 13 years ago

That did it. That's the problem with LINQ, the expression system is open to interpretation. Thanks.

craiggwilson commented 13 years ago

I'm going to reopen this issue. Even though there is a workaround, you shouldn't have to do this. I'll take a look when I can.

ronl commented 13 years ago

curious, what the Select was you added to resolve the issue. I have the same issue and only selects that project into aggregated values seems to work. After thinking about it, returning the actual grouped SensorData entities may be more than the Linq provider can really do. Correct me if really even possible. e.g. the following statements will fail with the same error...

var groups = datacoll.AsQueryable().GroupBy(x => x.PacketCounter).Select( gr => gr );
var groups = datacoll.AsQueryable().GroupBy(x => x.PacketCounter)
                                 .Select( gr =>  new {  Key=gr.Key,  Items=gr.ToList();

I am only able to get working tests that return back aggregated values of the entities, e.g.

var groups = datacoll.AsQueryable().GroupBy(x => x.PacketCounter)
                                .Select( gr =>  new {  Key=gr.Key,  MinValues=gr.Min( sd.Foo ),
                                                                  MaxValues=gr.Max( sd.Foo ) } );

Not sure at this time that I would need the capability to returned the actual grouped entities, was just experimenting with what the Linq provider could do. So far, pretty impressed with its real-time query and map/reduce generate capabilities.

craiggwilson commented 13 years ago

You're probably right. I need to take a look at the groupby stuff for things other than aggregates. I haven't needed it, so it isn't implemented, which is why I re-opened the ticket.