Vanligtvis måste du använda $filter i Aggregation Framework för att filtrera kapslad array. Men det finns ett enklare sätt att uppnå det med MongoDB .NET Driver och IQueryable gränssnitt.
Med tanke på den enklaste modellen:
public class MyModel
{
public string _id { get; set; }
public IEnumerable<MyNestedModel> myArray { get; set; }
}
public class MyNestedModel
{
public string other { get; set; }
}
och följande data:
var m = new MyModel()
{
_id = "1",
myArray = new List<MyNestedModel>() {
new MyNestedModel() { other = "stuff" },
new MyNestedModel() { other = "stuff" },
new MyNestedModel() { other = "stuff2" } }
};
Col.InsertOne(m);
du kan helt enkelt anropa .AsQueryable()
på din samling och sedan kan du skriva LINQ-fråga som kommer att översättas av MongoDB-drivrutinen till $filter
, försök:
var query = from doc in Col.AsQueryable()
where doc._id == "1"
select new MyModel()
{
_id = doc._id,
myArray = doc.myArray.Where(x => x.other == "stuff")
};
var result = query.ToList();
EDIT:
Alternativt kan du skriva $filter
del som en råsträng och använd sedan .Aggregate()
metod. Med det här tillvägagångssättet behöver du inte "karta" alla egenskaper men nackdelen är att du tappar typsäkerheten eftersom detta bara är en sträng, försök:
var addFields = BsonDocument.Parse("{ \"$addFields\": { myArray: { $filter: { input: \"$myArray\", as: \"m\", cond: { $eq: [ \"$$m.other\", \"stuff\" ] } } } } }");
var query = Col.Aggregate()
.Match(x => x._id == "1")
.AppendStage<MyModel>(addFields);
$addFields
används här för att skriva över befintligt fält.