Search code examples
c#mongodb-.net-driver

-1 in the index of a list in C#


I recently came across the below piece of code in our application

var updateDefinition = new UpdateDefinitionBuilder<OverviewProfile>()
            .Set(a => a.Advisors[-1].IsCurrent, advisor.IsCurrent);

In the above code, Advisors is a List and UpdateDefinitionBuilder is from MongoDB driver.

Could you please let me know the use of -1 in the index of the list?

Editing after the below comments/answers

The OverviewProfile class is as below:

public class OverviewProfile: BaseInvestorProfile
{
    //Other properties

    public List<Advisor.View.Advisor> Advisors { get; set; }
    public OverviewProfile(int id): base(id)
    {
        Advisors = new List<Advisor.View.Advisor>();
    }
}

And this is this the working code. This code updates the data to the mongo db based on the condition. There are no other methods inside this class, just other properties.

This is one class, but the same usage is there for properties of multiple class, and even when we add a new List property and check, it works fine.


Solution

  • You are using overload of UpdateDefinitionBuilder<T>.Set which expects Expression. This expression is not compiled and executed directly but instead is converted to native mongodb syntax and is used as part of mongo db query (same as how Entity Framework or other ORM converts expressions to SQL). This basically says "update all overview profiles and set IsCurrent flag of first advisor that matches criteria to advisor.IsCurrent value". Because mongodb allows negative indexes (meaning - relative to the end of collection) - C# mongodb driver can convert your expression to valid mongodb query (but see update below).

    Update. As stated here, -1 still has special meaning for mongodb C# driver. It will be converted to positional update operator $:

    the positional $ operator acts as a placeholder for the first element that matches the query document

    For example:

    var updateDefinition = new UpdateDefinitionBuilder<OverviewProfile>()
        .Set(a => a.Advisors[-1].IsCurrent, false);
    
    colleciton.UpdateOne(c => c.Advisors.Any(r => r.IsCurrent), updateDefinition);
    

    Will be converted to something like:

    "updates": [{
            "q": {
                "Advisors": {
                    "$elemMatch": {
                        "IsCurrent": true
                    }
                }
            },
            "u": {
                "$set": {
                    "Advisors.$.IsCurrent": false // <- your expression
                }
            }
        }
    ]
    

    However, point about negative index meaning relative to the end of colleciton in mongodb still holds, because any other negative index except -1 (for example, -2), will be converted to query like this:

    { "$set" : { "Advisors.-2.IsCurrent" : false} }