Search code examples
c#arraysmongodbmongodb-querymongodb-.net-driver

How to check last element's property of an array using MongoDB C# driver


I have model classes defined below. I am using MongoDB 6.0.

public class App
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }    

    public List<Version> Versions { get; set; } = new List<Version>();

    public bool IsDeleted { get; set; }
}

public class Version
{
    public DateTime DeployedDate { get; set; }

    public string DeploymentId { get; set; }

    public string Group { get; set; }
}

I would like to add another condition to the following C# query.

  • The Group property of the last element of the Versions array should not be equal to "12345".
var applicationFilter = Builders<App>.Filter.Eq(a => a.IsDeleted, false) &    
    Builders<App>.Filter.Exists(a => a.Versions, true) &    
    Builders<App>.Filter.SizeGt(a => a.Versions, 0);

Any help is appreciated.


Solution

  • Solution 1: Work with the $last operator

    Doubt that currently there is no $last operator in MongoDB .NET syntax. But you can query with BsonDocument. MongoDB .NET driver provides the implicit conversion from the BsonDocument to FilterDefinition<TDocument>.

    applicationFilter &= new BsonDocument("$expr",
        new BsonDocument("$ne",
            new BsonArray
            {
                new BsonDocument("$last", "$versions.group"),
                "12345"
            }));
    

    Solution 2: Work with LINQ3 provider

    If you use MongoDB.Driver with version 2.14 and above, you can utilize the query with the LINQ expression/way.

    Pre-requisites: Enable LINQ3 provider in MongoClientSettings.

    MongoClientSettings settings = MongoClientSettings.FromConnectionString(
        /* Connection string */
    );
    settings.LinqProvider = MongoDB.Driver.Linq.LinqProvider.V3;
    
    MongoClient _client = new MongoClient(settings);
    
    applicationFilter &= Builders<App>.Filter.Where(x => x.Versions.Last().Group != "12345");