Curious-programmer
Curious-programmer

Reputation: 813

Delete a nested object in mongo in C# with a filter

I have a Shipment object with a nested list of materials objects (note : _id refers to the shipmentId)

"_id" : "1",
"createddate" : "2018-10-18T16:25:59.245Z",
"attributes" : {       
        "materials" : [ 
            {
                "materialcode" : "string",             
                "status" : "Unmatched"
            }
        ]
    },

I would like to delete the the material of the corresponding shipment if the status = Unmatched. I am trying to use pull or pullfilter just not sure how to use it

here is what I have so far, (this does not build as I get error cannot covert lamda expression to field expression ):

Task<bool> DeleteShipmentMaterials(string ShipmentId, string MaterialId)
        {
       var shipment = await GetShipment(ShipmentId);
                foreach (var material in shipment.attributes.Materials)
                {
                    var update = Builders<Shipment>.Update.PullFilter(x => x.attributes.Materials, Builders<Shipment>.Filter.Eq(x => x.Id, shipment.Id));
                 .MaterialCode == material.MaterialCode),  );
                    await UpdateOneAsync(c => c.Id == shipment.Id, update, true);
                }

Upvotes: 1

Views: 810

Answers (1)

mickl
mickl

Reputation: 49945

No need to use foreach loop here. You can just use $pull an specify a condition - this will remove all the elements with specified status. In Mongo shell you can run:

db.shipments.update(
    { "_id" : "1" },
    { $pull: { "attributes.materials": { "status": "Unmatched" } } }
)

In C# code you can use PullFilter method to build your filter. Try:

var filter = Builders<Shipment>.Filter.Eq(x => x._id, "1");
var update = Builders<Shipment>.Update.PullFilter(x => x.attributes.materials, 
    material => material.status == "Unmatched");

Col.UpdateOne(filter, update);

Upvotes: 1

Related Questions