How can I delete nested array element in a mongodb document with the c# driver

mathinvalidnik picture mathinvalidnik · Feb 18, 2015 · Viewed 11.3k times · Source

I am new in the MongoDB world and now I am struggling of how can I delete, update element in a nested array field of a document. Here is my sample document:

{
    "_id" : ObjectId("55f354533dd61e5004ca5208"),
    "Name" : "Hand made products for real!",
    "Description" : "Products all made by hand",
    "Products" : [ 
        {
            "Identifier" : "170220151653",
            "Price" : 20.5,
            "Name" : "Leather bracelet",
            "Description" : "The bracelet was made by hand",
            "ImageUrl" : "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQii6JCvXtx0iJGWgpvSl-KrdZONKYzDwS0U8uDvUunjO6BO9Aj"
        }
    ]
} 

In my method, I get the id of the document and the id(Identifier) of the Product that I want to delete. Can anyone tell me how can I delete from the Products field the element having Identifier: 170220151653?

I tried:

var query = Query.And(Query.EQ("_id", categoryId), Query.EQ("Products.Identifier", productId));
var update = Update.Pull("Products", new BsonDocument() { { "Identifier", productId } });
myDb.Applications().Update(query, update);

as suggested here: MongoDB remove a subdocument document from a subdocument

But I get an error at

myDb.Applications()

It just can't be found.

SOLVED:

var pull = Update<Category>.Pull(x => x.Products, builder => builder.EQ(q => q.Identifier, productId));
collection.Update(Query.And(Query.EQ("_id", ObjectId.Parse(categoryId)), Query.EQ("Products.Identifier", productId)), pull);

Answer

neleus picture neleus · Feb 18, 2015

You are calling method Pull(string name, MongoDB.Bson.BsonValue value) and according to the docs it

Removes all values from the named array element that are equal to some value (see $pull)

and you provide { "Identifier", productId } as the value. I guess that mongo does not find that exact value.

Try to use the second overload of Pull with query-condition instead of exact value

Removes all values from the named array element that match some query (see $pull).

var update = Update.Pull("Products", Query.EQ("Identifier", productId));

UPDATE

Since you mention Category entity so I can suggest using lambda instead of Query.EQ:

var pull = Update<Category>.Pull(x => x.Products, builder =>
builder.Where(q => q.Identifier == productId));