[CSHARP-2002] Questions about the $filter operator in the aggregation pipleine Created: 14/Jun/17  Updated: 27/Oct/23  Resolved: 31/Aug/18

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

Type: Task Priority: Minor - P4
Reporter: Emanuel M Assignee: Unassigned
Resolution: Works as Designed Votes: 0
Labels: question
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

.NET Core 1.1, Windows 10 x64


Attachments: Text File Program.cs     Text File ProgramCorrectVersion.cs    

 Description   

Hello, I have a few questions regarding the mongodb C# driver, as the title says I haven't been able to figure out the $filter operator in the aggregation pipline.

The problem I'm trying to solve using a mongo query is the following, I have a collection with entries that contain an array with objects in it as follows:

{
    "_id" : ObjectId("some-unique-id"),
    "ref" : [ 
        {
            "name" : "something",
            "ref" : "Something/1234"
        },
       {
            "name" : "something",
            "ref" : "Something/4567"
        },
       {
            "name" : "else",
            "ref" : "Else/1234"
        }
    ]
}

I'm trying to project the sub array so it returns only some items, I've managed to do it using a json mongo query similar to the one described in the docs.

I didn't manage to generate one from C# code correctly. I've tried using two methods.
The IAggregateFluent Project() method accepts two overloads, mainly using an ProjectDefinition or an Expression<Func<TInput, TOutput>>.

The Project definition generates a json that projects the document in a non-aggregation manner

{ "ref": 1, "_id" :0 }

That's not sufficient as I need to filter the array.

The Expression<Func<TInput, TOutput>> generates it somewhat correctly but not quite.

This is the C# code that I pass to the Aggregate pipeline

 
Expression<Func<MongoEntry, IEnumerable<MongoReferenceComponent>>> projection = (entry) =>
                         entry
                             .ReferenceComponents
                             .Where(refr => refr.Name == "something");
 
var aggregation = source.Aggregate()
    .Match(filter)
    .Project(projection);
 
return (await aggregation.ToCursorAsync());

This is what it generates (raises an exception)

"$project": {
        "$filter": {
            "input": "$ref",
            "as": "item",
            "cond": {
                "$eq": [ "$$item.name", "something" ]
            }
        }
    }

And this is how it should look like

"$project": {
        "ref": {
            "$filter": {
                "input": "$ref",
                "as": "item",
                "cond": {
                    "$eq": [ "$$item.name", "something" ]
                }
            }
        }
    }



 Comments   
Comment by Emanuel M [ 13/Jul/17 ]

Followup: After I revisited the solution with a clean slate, I managed to generate the pipeline correctly. It seems that this wasn't a bug but a misinterpretation on my account of the projection operator. To be fair the examples are scarce on the aggregation matter and the documentation isn't always as helpful. As a side note do you know where I can write a followup with a detailed example of the $match and $project operators, I feel like I'm not the only one who'd find this useful ?

Edit: I uploaded the correct projection

Comment by Emanuel M [ 06/Jul/17 ]

Hey Craig thanks for replying, the exception I am getting is the following "Command aggregate failed: FieldPath field names may not start with '$'.." and I suspect that's because either I'm doing something wrong with generating the projection, either there's a bug involved. I managed to reproduce it with some code and I will attach the source file.

Comment by Craig Wilson [ 05/Jul/17 ]

Hi Emmanuel,

I have used your example code, and the generated $project is exactly the way it should be. That is to say, the one that is raising the error is correct. However, you indicated that it's raising an exception. Could you provide that exception?

Craig

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