I have following schema:
{
"_id": 1111,
"someProp": 10,
"arrayOfObjects": [
{
"type1": 1,
"prop1": 1,
"type2": "D2-1"
},
{
"type1": 2,
"prop1": 2,
"type2": "D2-2"
},
{
"type1": 3,
"prop1": 2,
"type2": "D2-3"
}
]
}
type1
is property that is contained in match filter. Example:
var arrayToMatch = new int[] { 1, 2 };
var matchFilter = Builders<MyObject>.Filter.Gte(x => x.SomeProp, 10)
& Builders<MyObject>.Filter.ElemMatch(x => x.ArrayOfObjects, Builders<ArrayObject>.Filter.In(y => y.Type1, arrayToMatch));
Filter works exactly as expected. After documents are filtered with match I want to project results, but so that arrayOfObjects
contains only objects that match filter inside projection.
Query
var arrayToMatchAsString = "[" + string.Join(",", arrayToMatch) + "]";
var results = await Collection
.Find(matchFilter)
.Project<ProjectionObject>($"{{ _id: 1, matches: {{ $filter: {{ input: '$arrayOfObjects', as: 'item', cond: {{ $in: ['$$item.type1', {arrayToMatchAsString}] }} }} }} }}")
.ToListAsync();
also works as expected, but I would like to write this query using C# driver.
I have:
var results = await Collection
.Aggregate()
.Match(matchFilter)
.Project(x => new ProjectionObject
{
x.Id,
Matches = x.ArrayOfObjects.Where(x => arrayToMatch.Contains(x.Type1))
})
.ToListAsync();
but Matches
gets translated as
{ "$filter" : { "input" : "$arrayOfObjects", "as" : "x", "cond" : { "$anyElementTrue" : { "$map" : { "input" : [1, 2], "as" : "x", "in" : { "$eq" : ["$$x", "$$x.type1"] } } } } } }
and I do not get any results
How can I write C# query that would get translated as
{ "$filter" : { "input" : "$arrayOfObjects", "as" : "item", "cond" : { "$in" : ["$$item.type1", [1,2]] } } }