-
Type:
Task
-
Resolution: Works as Designed
-
Priority:
Minor - P4
-
None
-
Affects Version/s: 2.4.4
-
Component/s: Operations
-
Environment:.NET Core 1.1, Windows 10 x64
-
None
-
None
-
None
-
None
-
None
-
None
-
None
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" ] } } } }