Въпросът не описва напълно случая на използване, така че измислих няколко потенциални опции, които да проучите въз основа на няколко предположения, по-специално те зависят от наличността на LINQ и насочването към един документ в даден момент ( и че вероятно не искате повече код, отколкото наистина ви е необходим):
1) Вариация на това, което имате. Използвайте стандартно find
с проекция и 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) Използвайте тръбопровода за агрегиране (можете да използвате същата проекция като по-горе)
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) Издърпайте документа обратно с всички елементи на масива, след което филтрирайте локално с помощта на LINQ. Положителната страна е, че това е малко количество четим код, но връща целия документ обратно преди филтриране. В зависимост от вашата точна употреба това може да е приемливо.
var items3 = collection.AsQueryable()
.SingleOrDefault(x => x.user == "Jone Doe")
.fooArray.Where(x => x.plot == "circle");
Ако LINQ наистина не е опция, тогава има пример тук това показва как можете да преобразувате проекцията в ненас LINQ. Напълно нетествано, но би било нещо от рода на:
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);