Thông thường, bạn cần sử dụng $ filter trong Aggregation Framework để lọc mảng lồng nhau. Tuy nhiên, có một cách dễ dàng hơn để đạt được điều đó bằng cách sử dụng Trình điều khiển MongoDB .NET và IQueryable giao diện.
Xem xét mô hình đơn giản nhất:
public class MyModel
{
public string _id { get; set; }
public IEnumerable<MyNestedModel> myArray { get; set; }
}
public class MyNestedModel
{
public string other { get; set; }
}
và dữ liệu sau:
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);
bạn có thể chỉ cần gọi .AsQueryable()
trên bộ sưu tập của bạn và sau đó bạn có thể viết truy vấn LINQ sẽ được trình điều khiển MongoDB dịch sang $filter
, hãy thử:
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();
CHỈNH SỬA:
Ngoài ra, bạn có thể viết $filter
một phần như một chuỗi thô và sau đó sử dụng .Aggregate()
phương pháp. Sử dụng phương pháp này, bạn không phải "ánh xạ" tất cả các thuộc tính tuy nhiên hạn chế là bạn đang mất an toàn kiểu vì đây chỉ là một chuỗi, hãy thử:
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
được sử dụng ở đây để ghi đè trường hiện có.