A pergunta não descreve completamente o caso de uso, então eu criei algumas opções potenciais para você explorar com base em algumas suposições, em particular, elas dependem da disponibilidade do LINQ e do direcionamento de um único documento por vez ( e que você provavelmente não quer mais código do que realmente precisa):
1) Uma variação do que você tem. Use um
find
padrão com uma projeção e expressão 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) Use o pipeline de agregação (você pode usar a mesma projeção acima)
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) Puxe o documento de volta com todos os elementos da matriz e filtre localmente usando LINQ. No lado positivo, esta é uma pequena quantidade de código legível, no entanto, traz todo o documento de volta antes da filtragem. Dependendo do seu uso exato, isso pode ser aceitável.
var items3 = collection.AsQueryable()
.SingleOrDefault(x => x.user == "Jone Doe")
.fooArray.Where(x => x.plot == "circle");
Se LINQ realmente não é uma opção, então há um exemplo aqui que mostra como você pode converter a projeção para não nós LINQ. Totalmente não testado, mas seria algo como:
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);