Reputation: 699
I have a collection with a following data
{
"_id": "4e3951905e746b3805000000",
"Name": "John",
"Surname": "Mayer",
"Comments": [
{
"_id": "4e3951965e746b8007000001",
"content": "a"
}
]
}
for instance i want to del a subdocument with id 4e3951965e746b8007000001 So this subdocument should be deleted
This my csharp code
public static void UpdateContentById(string id)
{
var defination = Builders<Client>.Update.PullFilter(p => p.Comments, c => c.Id == "4e3951965e746b8007000001");
db.UpdateOne(p => p.Id == id, defination);
}
That's the result I was expecting.
{
"_id": "4e3951905e746b3805000000",
"Name": "John",
"Surname": "Mayer"
}
Upvotes: 0
Views: 411
Reputation: 31282
When you remove the last element from an array, array field is not deleted by itself. Usually it's a desirable behavior. If you have a model like this:
public class Client
{
public ObjectId Id { get; set; }
public List<Comment> Comments { get; set; }
}
Comments
field will be deserialized as empty list. Unlike the case when Comments
field is missing in the database document, in this case Comments
property will be left as null
. This will require additional checks for null
in application logic or could cause NullReferenceException
. Unless you initialize the list when object is constructed:
public List<Comment> Comments { get; set; } = new List<Comment>();
Now Comments
will be set as empty list even if the property is missing in the document. However that is exactly the same as if Comments
array in the document was just left empty.
So I don't see much sense in deleting empty array fields. However if you want this behavior for some reason, you should do it by yourself with another update after element pull:
db.UpdateOne(p => p.Id == id, defination);
db.UpdateOne(p => p.Id == id && !p.Comments.Any(), Builders<Client>.Update.Unset(p => p.Comments));
Upvotes: 1