Вопрос не полностью описывает сценарий использования, поэтому я предложил несколько возможных вариантов для изучения на основе нескольких предположений, в частности, они зависят от доступности 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);