Search code examples
c#mongodbasp.net-coremongodb-.net-driver

No array filter found for identifier '-1'


I am developing a .NET application with MongoDB, using C# driver 2.14. My query is as follows:

I have an embedded array elements, eg:

{
    "_id" : 1,
        "Friends" : [
                {
                        "_id" : 2,
                        "FirstName" : "Bob",
                        "LastName":"Marley",
                        "Gender":"Male",
                        ...
                },
                {
                        "_id" : 3,
                        "Name" : "Jonson",
                        "LastName":"Charles",
                        "Gender":"Male",
                        ...
                },
                {
                        "_id" : 4,
                        "Name" : "Bob",
                        "LastName":"",
                        "Gender":"Male",
                        ...
                }
        ]
}

which has multiple fields in it. I need to update all the values in one of the nested documents.

I have written a code as follows:

var filter1 = Builders<BsonDocument>.Filter.Eq("_id", 1);
var filter2 = Builders<BsonDocument>.Filter.ElemMatch<BsonValue>("Friends", new BsonDocument(){ {"_id", 2 }});

var update = Builders<BsonDocument>.Update.Set("Friends.$[-1]", BsonDocument.Parse(JsonConvert.SerializeObject(object)));

await collection.UpdateAsync(filter1&filter2, update);

I am getting the exception as:

No array filter found for identifier '-1'

Can anyone please suggest whether it's the right approach?


Solution

  • It is an invalid syntax/statement in MongoDB for

    "Friends.$[-1]"
    

    You need arrayFilter to update document in the nested array field.

    using MongoDB.Bson;
    
    var filter1 = Builders<BsonDocument>.Filter.Eq("_id", 1);
    var filter2 = Builders<BsonDocument>.Filter.ElemMatch<BsonValue>("Friends"
        , new BsonDocument() { { "_id", 2 } });
    
    // Sample value to be updated
    var obj = new
    {
        _id = 2,
        FirstName = "Bobby",
        LastName = "Marley",
        Gender = "Female"
    };
    
    var arrayFilters = new[]
    {
        new BsonDocumentArrayFilterDefinition<BsonDocument>(
            new BsonDocument("friend._id", 2)
            )
    };
    
    var update = Builders<BsonDocument>.Update.Set("Friends.$[friend]", obj.ToBsonDocument());
    
    await collection.UpdateOneAsync(filter1 & filter2, update,
        options: new UpdateOptions { ArrayFilters = arrayFilters });
    

    Note:

    This statement is used to convert object to BsonDocument.

    BsonDocument.Parse(JsonConvert.SerializeObject(object))
    

    can be replaced with

    obj.ToBsonDocument()
    

    Output