[CSHARP-1429] Invalid query created when using unwind stage and match stage in Aggregate method Created: 01/Oct/15  Updated: 11/Mar/16  Resolved: 11/Mar/16

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 2.1
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Vincent Lainé Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

WIndows 10 x64 FR
Visual Studio 2015, .NET 4.5.2

Driver has been compiled from the latest source in github (git master (49ecd1630d2aa4e634e86e4dc88731ae4f77f400))


Issue Links:
Related
related to CSHARP-1430 LINQ OfType uses wrong projector when... Closed

 Description   

When using the Aggregate method like this:

var aggregate = collection.Aggregate()
                .Match(p => p.Id == entityId)
                .Unwind<Entity, SubEntity>(p => p.SubEntities)
                .OfType<SubEntityA>()
                .Match(s => s.A == aValue);
 
            aggregate = aggregate.SortBy(i => i.A);
            var cursor = await aggregate.ToCursorAsync().ConfigureAwait(false);

the generated query isn't correct. The output is:

[{ "$match" : { "_id" : "1" } }, 
{ "$unwind" : "$SubEntities" }, 
{ "$match" : { "_t" : "SubEntityA" } }, 
{ "$match" : { "A" : "A12" } }, { "$sort" : { "A" : 1 } }]

but should be:

[{ "$match" : { "_id" : "1" } }, 
{ "$unwind" : "$SubEntities" }, 
{ "$match" : { "SubEntities._t" : "SubEntityA" } }, 
{ "$match" : { "SubEntities.A" : "A12" } }, 
{ "$sort" : { "SubEntities.A" : 1 } }]



 Comments   
Comment by Craig Wilson [ 11/Mar/16 ]

Upon looking closer at this, there may be a mis-understanding about what exactly Unwind does. It does NOT do the same thing as SelectMany. Hence, by the way the aggregation is built-up, the output you have posted is correct. LINQ obviously makes this easier, so I'd encourage anyone needing to do something similar to this to simply use LINQ instead.

Craig

Comment by Craig Wilson [ 09/Mar/16 ]

Vincent,

We fixed the LINQ issue in version 2.1. Have you had a chance to test it?

Craig

Comment by Craig Wilson [ 01/Oct/15 ]

Please do share them. I can tell you now that OfType cannot be applied to embedded arrays because there isn't an aggregation expression that supports it. Server 3.2 includes a new $filter expression that will allow us to support OfType in embedded arrays.

Comment by Vincent Lainé [ 01/Oct/15 ]

Thanks Craig for your quick replies.

I confirm that OfType implementation in the Linq provider isn't complete we have some usecase where the provider throw exceptions because OfType isn't supported. If you're interested I can share those usecases.

Regards

Comment by Craig Wilson [ 01/Oct/15 ]

I've filed CSHARP-1430 to track the LINQ problem.

Comment by Craig Wilson [ 01/Oct/15 ]

Vincent, it looks like we have a bug here even in the LINQ implementation. I believe it's related to oftype... I'll work on this today.

Comment by Craig Wilson [ 01/Oct/15 ]

Hi Vincent,

Ok, so Unwind is not SelectMany (from LINQ). It behaves differently and requires some hoop jumping to make it work. I actually could not get the Aggregate method to do what you were wanting to do, so I'll leave this ticket open as it should be possible to, in some way, finagle it to work right.

However, since you are using 2.1, then might I suggest using LINQ for this. It ends up being much more elegant:

var query = collection.AsQueryable()
                .Where(p => p.Id == entityId)
                .SelectMany(p => p.SubEntities)
                .OfType<SubEntityA>()
                .Where(s => s.A == aValue)
                .OrderBy(i => i.A);
 
            Console.WriteLine(query);

Will generate this:

aggregate([
    { "$match" : { "_id" : "1" } }, 
    { "$unwind" : "$SubEntities" }, 
    { "$project" : { "SubEntities" : 1, "_id" : 0 } }, 
    { "$match" : { "SubEntities._t" : "SubEntityA" } }, 
    { "$match" : { "A" : "A12" } }, 
    { "$sort" : { "A" : 1 } }
])  

Which is almost exactly what you were wanting with an included $project in there.

Comment by Vincent Lainé [ 01/Oct/15 ]

Hi Craig.

Thanks for that, my mistake .
Also be award about the dropcollection which is still in the code ...

Again thanks for the quick delete.

Comment by Craig Wilson [ 01/Oct/15 ]

Hi Vincent, I'll have an answer for you shortly. For now, I've downloaded your attachment and noticed that your username and password were still in the connection string. I've deleted your attachment so these won't be public.

Craig

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