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);
3
  • you want to delete only Identifier or whole array ? Commented Feb 18, 2015 at 13:51
  • @yogesh the whole element that has that Identifier Commented Feb 18, 2015 at 13:52
  • stackoverflow.com/questions/34115181/… Commented Dec 8, 2015 at 6:29

6 Answers 6

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));
Sign up to request clarification or add additional context in comments.

1 Comment

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.
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);

1 Comment

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 ...
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;

Comments

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.

Comments

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"}}})

1 Comment

Yes. I checked this one. It just doesnt work for me. I need it as C# Driver code. But thanks :)
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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.