Hi,
I’m trying to update a property of a nested array. I’m able to update property that is nested only one level deep, but if it is a level deeper it gives me the “too many positional elements” error.
Is this a valid scheme or should I completely avoid to use an array that contains items that are again arrays?
Please let me know how to update the Container.Parents.Children.ChildProperty in my sample code:
(change the “child 2.2” to “child 2.2 - updated”).
If possible, I would prefer typed C# code .
using System.Text.RegularExpressions;
using MongoDB.Driver;
var test = new Test();
test.Run();
public class Test
{
private readonly string dbName = "test";
private readonly IMongoCollection<Container> collection;
public Test()
{
var connectionString = "mongodb://localhost:27017";
var client = new MongoClient(connectionString);
client.ListDatabaseNames().ToList()
.Where(db => Regex.IsMatch(db, $"^{dbName}.*")).ToList().ForEach(db => client.DropDatabase(db));
collection = client.GetDatabase(dbName).GetCollection<Container>($"{nameof(Container)}Collection");
}
public void Run()
{
var id = Guid.NewGuid();
var container = new Container(id, new List<Parent>
{
new Parent(new List<Child>
{
new Child("child 1.1"),
new Child("child 1.2")
}, "parent 1"),
new Parent(new List<Child>
{
new Child("child 2.1"),
new Child("child 2.2")
}, "parent 2")
}, "containerLevel");
collection.InsertOne(container);
// modify child 2.2 ChildProperty
var filter = Builders<Container>.Filter.Eq(c => c.Id, id)
& Builders<Container>.Filter.ElemMatch(e => e.Parents, p => p.ParentProperty == "parent 2")
& Builders<Container>.Filter.ElemMatch(e => e.Parents[-1].Children, p => p.ChildProperty == "child 2.2");
var update = Builders<Container>.Update.Set(c => c.Parents[-1].Children[-1].ChildProperty, "child 2.2 - updated");
collection.UpdateOne(filter, update); // sounds good, doesn't work
// 'A write operation resulted in an error.
// WriteError: { Category : "Uncategorized", Code : 2, Message : "Too many positional (i.e. '$') elements found in path 'Parents.$.Children.$.ChildProperty'" }.'
}
public record Container(Guid Id, IList<Parent> Parents, string ContainerProperty);
public record Parent(IList<Child> Children, string ParentProperty);
public record Child(string ChildProperty);
}