MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mongodb C#-Treiber gibt nur übereinstimmende Unterdokumente im Array zurück

Normalerweise müssen Sie $filter in Aggregation Framework verwenden, um verschachtelte Arrays zu filtern. Es gibt jedoch einen einfacheren Weg, dies mit dem MongoDB .NET-Treiber und IQueryable zu erreichen Schnittstelle.

Betrachtet man das einfachste Modell:

public class MyModel
{
    public string _id { get; set; }
    public IEnumerable<MyNestedModel> myArray { get; set; }
}

public class MyNestedModel
{
    public string other { get; set; }
}

und folgende Daten:

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);

Sie können einfach .AsQueryable() aufrufen in Ihrer Sammlung und dann können Sie eine LINQ-Abfrage schreiben, die vom MongoDB-Treiber in $filter übersetzt wird , versuchen Sie:

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();

BEARBEITEN:

Alternativ können Sie $filter schreiben Teil als Rohstring und verwenden Sie dann .Aggregate() Methode. Mit diesem Ansatz müssen Sie nicht alle Eigenschaften "zuordnen", aber der Nachteil ist, dass Sie die Typsicherheit verlieren, da dies nur ein String ist, versuchen Sie es mit:

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 wird hier verwendet, um vorhandene Felder zu überschreiben.