简体   繁体   中英

Given this model, how to delete a nested array item with updateOne (mongoose)?

I am trying to remove an array item with "updateOne" method but my query is not matching the right record in the model structure that I have. Given an email, I would like to find the array item with the provided email and pulls it out, remove it. (There is no array item with the same email)

My model is like so:

var mongoose = require('mongoose');

var teamMemberModelSchema = new mongoose.Schema({
     _id: false,
    "email": {
        "type": String,
        "required": true,
        "minlenght": 5,
        "maxheight": 50
    },
    "name": {
        "type": String,
        "required": true,
        "minlenght": 5,
        "maxheight": 256
    },
    "role": {
        "type": String,
        "required": true,
        "minlenght": 20,
        "maxheight": 256
    },
    "twitter": {
        "type": String,
        "required": true,
        "minlenght": 1,
        "maxheight": 100
    },
    "facebook": {
        "type": String,
        "required": true,
        "minlenght": 1,
        "maxheight": 100
    },
    "linkedin": {
        "type": String,
        "required": true,
        "minlenght": 1,
        "maxheight": 100
    },
});

var teamModelSchema = new mongoose.Schema({
    "title": {
        "type": String,
        "required": true,
        "minlenght": 5,
        "maxheight": 20
    },
    "headline": {
        "type": String,
        "required": true,
        "minlenght": 5,
        "maxheight": 30
    },
    "description": {
        "type": String,
        "required": true,
        "minlenght": 5,
        "maxheight": 80
    },
    "members": [teamMemberModelSchema]
}, { collection: 'team' });

teamModelSchema.set('collection', 'team');
mongoose.model('team', teamModelSchema)

And the approach that I am trying is the following:

module.exports.removeMember = function (req, res) {
  const email = req.params.email;
  const query = { "members.email": email };
  const pull = { $pull: { "members.$.email": email } };

  try {
    var message = teamMsg.teamMemberRemoveSuccess;

    TeamModel.updateOne(query, pull);

    responseUtilities.sendJSON(res, false, { message: message });
  } catch (err) {
    console.log(err.message);
    responseUtilities.sendJSON(res, err, { message: err.message });
  }
};

It executes with no errors, but nothing is updated.

I have tried some others alternatives with "FindOneAndUpdate" and "FindOneAndRemove" but, I could not find a solution.

Any ideas?

give this query a try:

db.collection.update(
    { 'members.email': 'email@address' },
    { $pull: { members: { email: 'email@address' } } },
    { multi: true }
)

You can use findOneAndUpdate with $pull operator for this task.

For removing items from an array of documents you can check MongoDb docs

You need to use await or then block to query. I used await, and made the function asynchronous by adding async keyword. We also need empty query object.

I also added the new: true option, to return the updated object to check if the item is deleted.

You need to handle the case where no document matches, I added a TODO for you.

module.exports.removeMember = async function(req, res) {
  const email = req.params.email;
  const query = {};

  const pull = {
    $pull: {
      members: {
        email: email
      }
    }
  };

  const options = {
    new: true
  };

  try {
    var message = teamMsg.teamMemberRemoveSuccess;

    const result = await TeamModel.updateOne(query, pull, options);

    console.log(result);

    if (!result) {
      //TODO: return 400-Bad Request or 404 - Not Found
    } else {
      responseUtilities.sendJSON(res, false, { message: message });
    }
  } catch (err) {
    console.log(err.message);
    responseUtilities.sendJSON(res, err, { message: err.message });
  }
};

Try using the update() method and async/await :

module.exports.removeMember = async function (req, res) {

    const email = req.params.email;
    console.log(`email = ${email}`)   // Make sure correct value is coming thru

    const query = { "members.email": email };
    const pull = { $pull: { "members.$.email": email } };
    const options = { multi: true }

    try {

        var message = teamMsg.teamMemberRemoveSuccess;

        await TeamModel.update( query, pull, options );


        responseUtilities.sendJSON(res, false, { "message": message });

    } catch (err) {
        console.log(err.message);
        responseUtilities.sendJSON(res, err, { "message": err.message });
    }
};

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