nogood
nogood

Reputation: 1320

How to update a property of an complexObj. inside a Document inside a List<complexObj>? MongoDB C# net.Driver

how to update one property of a document in MongoDb with C# net.Driver. My data model in C# looks like this:

public class MyMediListsWrapper
{
    [BsonId]
    public Guid Id { get; set; }
    public DateTime Datum { get; set; }
    public bool IsActiv { get; set; }
    public List<Medi> MediLsts { get; set; }
}

public class Medi
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Typ { get; set; }
    public string Vmax { get; set; }
}

Now I want to update only one property of one Obj. (Vmax='Test') of the nested List MediLsts.

I wand to filter the collection MyMediListsWrapper by SingleOrDefault IsActiv=true and then I want to filter 'in this Document' the Medi-Obj. from the nested List inside by Guid='XcPwoEaB8Ey7XR1AEB+fLQ==' and then update Vmax='Test'.

I have a little bit of code, but it doesn't achieve what I want. I have trouble to do the filter first for IsActiv and then filter inside of that Document again for a different property. And I don't know how to write the code for the update later (if found). Thx for help.

My Code:

var db = client.GetDatabase(MySecret.MyMongoDbName);
var myMediListsWrapper = db.GetCollection<MyMediListsWrapper>(MySecret.MyWrapperColName);

var filter = Builders<MyMediListsWrapper>.Filter;
var filterColAndFilterLstObj = filter.And(
    filter.Eq(x => x.IsActiv, true),
    filter.ElemMatch(x => x.MediLsts, lst => lst.Id == mySearchGuid));

//Just a Test -- I want to UPDATE a property NOT find a entry
//and this is WRONG because it give me a obj of the outer class not the Medi-Obj.
var result = await myMediListsWrapper.Find(filterColAndFilterLstObj).SingleOrDefaultAsync(); ```

Upvotes: 1

Views: 873

Answers (1)

Dĵ ΝιΓΞΗΛψΚ
Dĵ ΝιΓΞΗΛψΚ

Reputation: 5679

the following update command should do the trick:

await collection.UpdateOneAsync(
    filter: w => w.IsActiv && w.MediLsts.Any(m => m.Id == mySearchGuid),
    update: Builders<MyMediListsWrapper>.Update.Set(m => m.MediLsts[-1].Vmax, "TEST"));

the thing to note here is the [-1] array/list index above. the driver translates that to the following $set operation:

$set: { "MediLsts.$.Vmax" : "TEST" }

-1 index position is something special the mongo driver uses to denominate $ which is the first positional operator.

i.e. update the first array element that qualifies for the $elemMatch condition of the filter.

.MediLsts.Any(...) is the LINQ equivalent of filter.ElemMatch(...)

Upvotes: 1

Related Questions