[CSHARP-3293] Linq Where method is ignored inside Collection.AsQueryable().GroupBy() of MongoDB.Driver 2.11.2 Created: 20/Dec/20  Updated: 28/Oct/23  Resolved: 16/Feb/22

Status: Closed
Project: C# Driver
Component/s: Linq
Affects Version/s: 2.11.2
Fix Version/s: 2.14.0

Type: Bug Priority: Major - P3
Reporter: God God Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

C# .Net


Issue Links:
Related
is related to CSHARP-4063 Support Nullable HasValue and Value p... Closed
Epic Link: CSHARP-3615

 Description   

Im writing some service in C# and I have to use MongoDB.Driver 2.11.2. I have some issue when grouping my list of items. It looks like a bug. This is my code:

var totals = Collection.AsQueryable().GroupBy(s => s.StoreId, (key, group) => new Test
        {
            Key = key,
 
            LabOnHandTestCount =
                group.Count(groupItem => groupItem.IsLab.HasValue && groupItem.IsLab.Value),
 
            LabOnHandPrice =
                group.Where(groupItem => groupItem.IsLab.HasValue && groupItem.IsLabd.Value)
                    .Sum(z => z.TotalCost),
 
 
            LabOnHandPrice2 =
                group.Sum(g=> g.IsLa.HasValue && g.IsLab.Value ? g.TotalCost:0),
 
            LabOnHandPrice3 =
             group.Where(gg => gg.IsLab.Value == true).Sum(s=>s.TotalCost),
 
        }).ToList();

I got different results from next lines.

  • first line:

LabOnHandPrice = group.Where(groupItem => groupItem.IsLab.HasValue && groupItem.IsLabd.Value)
             .Sum(z => z.TotalCost)

  • second line(the right result):

LabOnHandPrice2 = group.Sum(g=> g.IsLa.HasValue && g.IsLab.Value ? g.TotalCost:0),

It looks like "Where" method of "first line" got ignored and calculation performed on wrong values. And also the result of the "first line" does not changes if i change a condition. I did not find any information on MongoDB official site.

 

Why "Where" method got ignored and i have different results? Is there any solution?

Tnx in advance.



 Comments   
Comment by James Kovacs [ 16/Feb/22 ]

This issue has been fixed in the new LINQ provider (known as LINQ3), which is included in the 2.14 release. Unfortunately it revealed an issue around our handling of nullable types in GroupBy. I have filed CSHARP-4063 to track this new issue.

The following code using bool instead of bool? works as expected:

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
 
var settings = new MongoClientSettings { LinqProvider = LinqProvider.V3 };
var client = new MongoClient(settings);
var db = client.GetDatabase("test");
var coll = db.GetCollection<Store>("csharp3293");
 
var query = coll.AsQueryable().GroupBy(s => s.StoreId, (key, group) => new {
            Key = key,
 
            LabOnHandTestCount =
                group.Count(groupItem => groupItem.IsLab),
 
            LabOnHandPrice =
                group.Where(groupItem => groupItem.IsLab)
                    .Sum(z => z.TotalCost),
 
 
            LabOnHandPrice2 =
                group.Sum(g=> g.IsLab ? g.TotalCost : 0),
 
            LabOnHandPrice3 =
             group.Where(gg => gg.IsLab == true).Sum(s=>s.TotalCost),
 
        });
 
Console.WriteLine(query);
var totals = query.ToList();
 
record Store(int StoreId, bool IsLab, int TotalCost);

The resulting MQL correctly filters the grouped items:

test.csharp3293.Aggregate([
    { "$group" : { "_id" : "$StoreId", "_elements" : { "$push" : "$$ROOT" } } },
    { "$project" : {
        "Key" : "$_id",
        "LabOnHandTestCount" : { "$size" : { "$filter" : { "input" : "$_elements", "as" : "groupItem", "cond" : "$$groupItem.IsLab" } } },
        "LabOnHandPrice" : { "$sum" : { "$map" : { "input" : { "$filter" : { "input" : "$_elements", "as" : "groupItem", "cond" : "$$groupItem.IsLab" } }, "as" : "z", "in" : "$$z.TotalCost" } } },
        "LabOnHandPrice2" : { "$sum" : { "$map" : { "input" : "$_elements", "as" : "g", "in" : { "$cond" : { "if" : "$$g.IsLab", "then" : "$$g.TotalCost", "else" : 0 } } } } },
        "LabOnHandPrice3" : { "$sum" : { "$map" : { "input" : { "$filter" : { "input" : "$_elements", "as" : "gg", "cond" : { "$eq" : ["$$gg.IsLab", true] } } }, "as" : "s", "in" : "$$s.TotalCost" } } }, "_id" : 0 } }])

I have closed this issue as resolved. Please follow CSHARP-4063 for the nullables in GroupBy issue.

Sincerely,
James

Comment by God God [ 07/Mar/21 ]

Hi, is there is any progress with this bug? Tnx

Comment by Boris Dogadov [ 24/Dec/20 ]

Hi denis@r2net.com !
Thank you for bringing this up to our attention. LINQ operators like Where/Select/Take are currently ignored by our LINQ translator within the GroupBy expression.
We will be investigating this issue further.

Comment by God God [ 20/Dec/20 ]

typo in bulleted "first line". Should be:

LabOnHandPrice = group.Where(groupItem => groupItem.IsLab.HasValue && groupItem.IsLab.Value).Sum(z => z.TotalCost)

Generated at Wed Feb 07 21:44:55 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.