I want to use $map and $filter option of aggregation framework utilizing C# mongodb driver native functions.
Is there any way to do that? If yes can you put some code examples please?
I searched the official documentation of Mongo DB but found nothing.
The following code is in mongo shell script and I want to translate to C# mongodb driver.
var pipeline =
[
{
$match:{
ExId: {$in: [ObjectId('5d112f91cb865c02b0714d56'), ObjectId("5d168d2c305196e45e73f4a7")]}
}
},
{
$project:{
ExId: 1,
ArrayObject: {
$map:{
'input': '$ArrayObject',
'as': 'itemA',
'in':{
'Name': '$$itemA.Name',
'FilterHere': {
$filter: {
input: '$$itemA.FilterHere',
as: 'item',
cond: {
$eq: ['$$item.Sent', true]
}
}
}
}
}
}
}
}
]
db.getCollection('MyColection').aggregate(pipeline)
I expect the following output into a C# object:
{
"_id" : ObjectId("5d444527cb865d28e8572d8d"),
"ExId" : ObjectId("5d112f91cb865c02b0714d56"),
"ArrayObject" : [
{
"Name" : 130774,
"FilterHere" : [
{
"Code" : 15900181,
"SentDate" : ISODate("2019-08-02T11:13:11.732Z"),
"Sent" : true
},
{
"Code" : 15900184,
"SentDate" : ISODate("2019-08-02T11:13:11.735Z"),
"Sent" : true
}
]
}
]
}
Thanks.
You can find the MongoDB C# Driver Aggregation Documentation here. For constructing an aggregation pipeline in the C# Driver, you have 3 options.
Builder
class.BsonDocument
builders to construct a "raw" aggregation. There is limited, or no type safety using this method.The first 2 options require that you create the appropriate classes as the compiler will enforce type safety.
The "raw" conversion of the aggregation you provided to option 3 is fairly straightforward, albeit a little verbose.
var foo = new BsonDocument("$project",
new BsonDocument("ExId", 1).Add("ArrayObject",
new BsonDocument("$map",
new BsonDocument("input", "$ArrayObject").Add("as", "itemA").Add("in",
new BsonDocument("Name", "$$itemA.Name").Add("$filter",
new BsonDocument("input", "$$itemA.FilterHere").Add("as", "item").Add("cond",
new BsonDocument("$eq", new BsonArray().Add("$$item.Sent").Add(true))))))));
Unfortunately, since I don't know what your input classes look like, it is hard for me to directly translate your pipeline into code. However, looking at the Expressions Documentation, it appears that $map
is used for .Select
LINQ and $filter
is used for .Where
LINQ. This would mean, your code looks something like
col.Aggregate()
.Match(doc => ids.Contains(doc.ExId))
.Project(doc =>
new {
ExId = doc.ExId,
ArrayObject = doc.ArrayObject.Select(x =>
new
{
Name = x.Name,
FilterHere = x.FilterHere.Where(y => y.Sent == true)
})
});
Since I don't have your actual classes, I could only really guess what they look like, StartObject
is my best guess.