I’m having trouble deleting an document in an array using the offical mongodb c# driver. What i’m trying to do is also return the document that was deleted.
Here’s what my class looks like:
public class Holder
{
public string Owner { get; set; }
public List<Card> Cards { get; set; }
}
public class Card
{
public string Id { get; set; }
public string Name { get; set; }
public string Placement { get; set; }
}
And here is an exerpt of the document:
{
"owner": "656dd33e0300"
"cards" : [
{
"id": "s39CNzu4Na3",
"name" : "Department",
"placement" : "8a"
},
...
]
}
My first thought was to just get the card and then delete it using the following:
var filter = Builders<Card>.Filter.Eq(x => x.Id, cardId);
var res = await collection.DeleteOneAsync(
Builders<Holder>.Filter.Eq(e => e.Owner, owner) &
Builders<Holder>.Filter.ElemMatch(e => e.Cards, filter)
);
try {
return res.DeletedCount > 0;
}
catch (Exception ex) {
throw;
}
But that just ended up deleting all the cards in the list.
I’ve been trying to use FindOneAndDeleteAsync
but i can’t get it to work.
2
Answers
From your code, you are deleting the entire
Holder
document but not removing theCard
element from theCards
array in theHolder
document.I don’t think the MongoDB .NET driver supports removing and returning the deleted element (API). Thus, you should:
Filter the document and get the filtered
Card
elements.Pull
theCard
element(s) which is matched from theCards
array.Return
res.ModifiedCount > 0
indicates the card element is removed and the items removed.As far as I understand your question, you do not want to delete the root document, but remove a sub-document from an array. You can do this using an update-Statement (delete is for deleting root documents as a whole).
In order for this to work, you need to create a filter that finds the document and then run an update with a
PullFilter
on the document.In addition, you want to return the sub-document that you deleted during the update. There is no statement to return the sub-document, but you can use
FindOneAndUpdateAsync
to return the root document in the state before the sub-document was removed: