How do I modify in Mongo (C# driver) a single element in a nested property (array) without retrieving the whole document?
public class Element
{
public int Value {get; set;}
public string Name {get; set;}
}
public class Document
{
public Element [] Elements {get; set;}
}
In example I want to find the element with name "Car" and sets its value to 4 in a single query.
You need $ positional operator where you can specify document-level condition and array-level condition to find single nested item in an array of particular document. In C# $
sign is represented by -1
passed as an index of your model array. Try:
var col = mydb.GetCollection<Document>("collectionName");
var id = new ObjectId("5babaaf5509f6d342da5abaa");
var elementName = "Car";
var newValue = 2;
var filterBuilder = Builders<Document>.Filter;
var filter = filterBuilder.Eq(x => x.Id, id) &
filterBuilder.ElemMatch(doc => doc.Elements, el => el.Name == elementName);
var updateBuilder = Builders<Document>.Update;
var update = updateBuilder.Set(doc => doc.Elements[-1].Value, newValue);
Col.UpdateOne(filter, update);
Update: -1 is not supported in MongoDB.Driver 2.19 in .NET 6, you'll get
Expression not supported: x.Elements.get_Item(-1) because negative indexes are not valid. To use the positional operator $ use FirstMatchingElement instead of an index value of -1.
Just include that using MongoDB.Driver.Linq
statement and replace the line above.
using MongoDB.Driver.Linq;
var update = updateBuilder.Set(doc => doc.Elements.FirstMatchingElement().Value, newValue);