简体   繁体   中英

How to delete subdocument using mongoose?

I have a mongoDB with the following schema:

const jobSchema = new mongoose.Schema({
    companyTitle: String,
    status: String,
    companyURL: String,
    jobTitle: String,
    jobURL: String,
    jobDescription: String,
    contactName: String,
    contactRole: String,
    contactPhone: String,
    contactEmail: String,
    tasks: [Task.schema]
})

 const taskSchema = new mongoose.Schema({
    taskItem: String,
    isCompleted: Boolean
})

When a user clicks a button, the job._id and task._id are sent to my server where the specific task should be deleted from the database. Currently, the route deletes the parent (job) instead of the child (task). Any ideas how to target the task instead? Thanks in advance!

app.js

app.delete('/tasks/:jobId/:taskId', (req, res) => {
    const jobId = req.params.jobId
    const taskId = req.params.taskId

    Job.findOneAndDelete(
        {'_id': jobId, 'tasks._id': taskId},
        function (error, doc) {
            if (error) {
                console.log(error)
            } else {
                console.log(doc)
            }
        }
    )
})

You should use findOneAndUpdate instead of findOneAndDelete . You can refactor your code like this:

app.delete('/tasks/:jobId/:taskId', async (req, res) => {
  const jobId = req.params.jobId
  const taskId = req.params.taskId

  Job.findOneAndUpdate(
      {"_id": jobId },
      {"$pull": {"tasks": {"_id": taskId}}},
      {new:true}, 
      function (error, doc) {
        if (error) {
            console.log(error)
        } else {
            console.log(doc)
        }
      }
  );

})

Your code delete the parent because Mongo remove a document which match the query. In this case, your "parent" match the query because it has a child with the given _id .

With query findOneAndDelete({'_id': jobId, 'tasks._id': taskId}) you are telling mongo: "Delete one document where the _id is jobId and some _id into tasks array is taskId ".

You have to use$pull in an update operation:

Something like

Job.updateOne(
  {"_id": jobId},
  {
    "$pull": {
      "tasks":{
        "_id": taskId
      }
    }
  }
)

Note that update has two objects: First one is the object to update and second one the "action" to do. In this case pull the subtask with the given _id .

This query tell to mongo: Search one object with the given _id and remove the tasks subdocument which _id is taskId .

Example here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM