Reputation: 1320
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
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