0

I'm trying to remove a document that is nested inside of an array which is nested inside of a document in MongoDB.

Schema

{
  "_id": 12345,
  "id": 12345,
  "name": "Test",
  "links": [],
  "training": [],
  "about": [
    {
      "contents": "Test Contents 0",
      "heading": "Test Heading 0"
    },
    {
      "contents": "Test Contents 1",
      "heading": "Test Heading 1"
    },
    {
      "contents": "Test Contents 2",
      "heading": "Test Heading 2"
    }
  ]
}

I want to remove the sub doc that matches the route

'/:_id/:section/:item'

Such that if I send a DELETE to /12345/about/1, the sub doc containing "Test Heading 1" will be removed entirely.

I've tried many different methods such as

.delete(function (req, res) {
    var section = req.params.section_name;
    var item = req.params.item;

    Tool.findOne({'id': req.params._id}, function (err, tool) {
        tool.set(section[item], null);
        tool.save(function (err) {
            res.send(err);
        })
    });
});

But none seem to work.

Any help would be greatly appreciated.

2 Answers 2

1

This should work perfectly

.delete(function (req, res) {
    var section = req.params.section_name;
    //convert string to int
    var item = +req.params.item; //or use parseInt(req.params.item)

    Tool.findOne({'id': req.params._id}, function (err, tool) {
        tool[section].splice(item, 1);
        tool.save(function (err) {
            res.send(err);
        })
    });
});

It's converted to

tool[section].splice(item, 1);
tool.about.splice(1, 1); //remove 1 item from given index

About splice

array.splice(index, 1);

The second parameter of splice is the number of elements to remove. Note that splice modifies the array in place and returns a new array containing the elements that have been removed.

Sign up to request clarification or add additional context in comments.

1 Comment

Strange. It's not setting it to undefined. It's getting the correct document but it's not actually setting it
0
Tool.findOneAndUpdate(
{
   "_id": req.params._id, "about.heading": "Test Heading 1" 
   // 1. query above will target the document by _id.
   // 2. search [about] and get index then store it at "$",
   // 3. "Test Heading 1" is located at about[1], store it at "$"
   // 4. imagine this line is executed => var $ = 1
}, 
{
   $unset: {"about.$": 1} 
}, 
{
   new:true //means return the updated document (new instead old)

}) 
.exec((err, tool)=>{
    if(err) console.log(err)
})

1 Comment

Maybe I wasn't clear but my intention is to remove the entire sub-doc completely that matches /id/section/item. See: "Such that if I send a DELETE to /12345/about/1, the sub doc containing "Test Heading 1" will be removed entirely." Basically, I'm removing an item (given an index) in an array (given the name of the array) within a document (given its _id or id)

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.