Biasanya Anda perlu menggunakan $filter dalam Kerangka Agregasi untuk memfilter array bersarang. Namun ada cara yang lebih mudah untuk mencapainya dengan menggunakan MongoDB .NET Driver dan IQueryable antarmuka.
Mempertimbangkan model yang paling sederhana:
public class MyModel
{
public string _id { get; set; }
public IEnumerable<MyNestedModel> myArray { get; set; }
}
public class MyNestedModel
{
public string other { get; set; }
}
dan data berikut:
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);
Anda cukup memanggil .AsQueryable()
pada koleksi Anda dan kemudian Anda dapat menulis kueri LINQ yang akan diterjemahkan oleh driver MongoDB ke $filter
, coba:
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();
EDIT:
Atau Anda dapat menulis $filter
bagian sebagai string mentah dan kemudian gunakan .Aggregate()
metode. Dengan menggunakan pendekatan ini, Anda tidak perlu "memetakan" semua properti, namun kekurangannya adalah Anda kehilangan keamanan tipe karena ini hanya string, coba:
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
digunakan di sini untuk menimpa bidang yang ada.