Pytanie nie opisuje w pełni przypadku użycia, więc wymyśliłem kilka potencjalnych opcji do zbadania w oparciu o kilka założeń, w szczególności zależą one od dostępności LINQ i kierowania do pojedynczego dokumentu na raz ( i że prawdopodobnie nie chcesz więcej kodu, niż naprawdę potrzebujesz):
1) Odmiana tego, co masz. Użyj standardowego find
z projekcją i wyrażeniem LINQ.
var projection = Builders<ShapeDocument>.Projection
.Expression(x => x.fooArray.Where(y => y.plot == "circle"));
var items1 = collection
.Find(x => x.user == "Jone Doe")
.Project(projection)
.ToList();
2) Użyj potoku agregacji (możesz użyć tej samej projekcji co powyżej)
var pipeline = collection
.Aggregate()
.Match(x => x.user == "Jone Doe")
.Project(i => new
{
x = i.fooArray.Where(x => x.plot == "circle")
});
var items2 = pipeline.SingleOrDefault();
3) Wyciągnij dokument z powrotem ze wszystkimi elementami tablicy, a następnie filtruj lokalnie za pomocą LINQ. Plusem jest to, że jest to niewielka ilość czytelnego kodu, jednak przywraca cały dokument przed filtrowaniem. W zależności od dokładnego zastosowania może to być akceptowalne.
var items3 = collection.AsQueryable()
.SingleOrDefault(x => x.user == "Jone Doe")
.fooArray.Where(x => x.plot == "circle");
Jeśli LINQ naprawdę nie jest opcją, to jest przykład tutaj to pokazuje, jak możesz przekonwertować projekcję na nie nas LINQ. Całkowicie niesprawdzone, ale byłoby to coś w stylu:
var filter = new BsonDocument {
{"input", "$items"},
{"as", "item" },
{"cond", new BsonDocument {
// Fill in the condition values
{ "", new BsonArray { "", xxx } } }
}
};
var project = new BsonDocument {
{ "items", new BsonDocument { { "$filter", filter} } }
};
var pipeline = collection.Aggregate().Project(project);