C# nested element update

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

Hi, @Ladislav_Chvila,

Reviewing your C# code and the error, you are attempting to use nested positional operators in your update statement. This is not permitted by the server and the error that you received back is a server error, not a .NET/C# driver error. Trying a similar operation (with an empty filter for ease of typing) in the shell, we can see the server return the same error:

test> db.coll.updateMany({}, {$set: { "Parents.$.Children.$.ChildProperty": 42 }})
MongoServerError: Too many positional (i.e. '$') elements found in path 'Parents.$.Children.$.ChildProperty'

I would strongly recommend that you to reconsider your schema for this reason among others.

Sincerely,
James

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.