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

6

15

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);
Matroclinous answered 18/2, 2015 at 13:46 Comment(3)
you want to delete only Identifier or whole array ?Upanchor
@yogesh the whole element that has that IdentifierMatroclinous
#34115681Arsenopyrite
S
15

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));
Strick answered 18/2, 2015 at 14:20 Comment(1)
Update<Category> hmmm, you didn't mention that you have Category type... Anyway this is the strongly-typed case of my solution, please dont forget to mark the answer.Strick
C
10

Solution with C# MongoDB Driver. Delete a single nested element.

var filter = Builders<YourModel>.Filter.Where(ym => ym.Id == ymId);
var update = Builders<YourModel>.Update.PullFilter(ym => ym.NestedItems, Builders<NestedModel>.Filter.Where(nm => nm.Id == nestedItemId));
_repository.Update(filter, update);
Circumscribe answered 8/8, 2020 at 10:51 Comment(2)
thank you, been trying to do this for two days.Pt
Is using the Builder in the 2nd argument of PullFilter necessary? A lambda automatically infers the NestedModel type, so it'd be nm => nm.Id == nestedItemId instead of Builders<NestedModel>.Filter ...Stanton
P
4

I had the same of deleting elements from the nested array but after research, I found this piece of working code.

var update = Builders<Category>.Update.PullFilter(y => y.Products, builder => builder.Identifier== productId);
var result = await _context.Category.UpdateOneAsync(filter, update);
return result.IsAcknowledged && result.ModifiedCount > 0;
Proselyte answered 8/2, 2020 at 5:53 Comment(0)
U
3

I was also facing the same problem and then finally after doing lot of R&D, I came to know that, you have to use PullFilter instead of Pull when you want to delete using filter.

Upcast answered 21/8, 2015 at 11:56 Comment(0)
U
0

Hi as per my understanding you want to remove whole matched elements of given id and identifier so below query will solve your problem but I don't know how to convert this into C#, here mongo $pull method used.

db.collectionName.update({"_id" : ObjectId("55f354533dd61e5004ca5208")}, {"$pull":{"Products":{"Identifier":"170220151653"}}})
Upanchor answered 18/2, 2015 at 14:3 Comment(1)
Yes. I checked this one. It just doesnt work for me. I need it as C# Driver code. But thanks :)Matroclinous
C
0

Solution for C# MongoDB Driver. You can set empty [] the nested array.

var filter = Builders<MyUser>.Filter.Where(mu => mu.Id == "my user id");
var update = Builders<MyUser>.Update.Set(mu => mu.Phones, new List<Phone>());
_repository.Update(filter, update);
Circumscribe answered 5/12, 2019 at 11:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.