如何使用updateOne(mongoose)删除嵌套数组项?给定此模型。

3
我想使用“updateOne”方法移除一个数组项,但我的查询没有匹配到我拥有的模型结构中正确的记录。给定一个电子邮件,我希望找到提供的电子邮件的数组项并将其拉出、移除它。(不存在相同电子邮件的数组项)
我的模型如下:
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)

我正在尝试的方法如下:

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

代码没有报错,但是没有更新任何内容。

我尝试了一些其他使用"FindOneAndUpdate"和"FindOneAndRemove"方法的替代方案,但是我没有找到解决办法。

有什么想法吗?


你有检查查询 { "members.email": email } 是否返回结果吗? - Genosite
是的,我做了。但是没有任何内容被删除或更新。 - Olavo Alexandrino
你是想获取整个members对象,其中{"members.email": email},还是只想从members对象中删除email字段? - whoami - fakeFaceTrueSoul
@whoami 我想要删除具有提供的电子邮件的整个成员,而不仅仅是其电子邮件字段。 - Olavo Alexandrino
3个回答

1
尝试执行以下查询:
db.collection.update(
    { 'members.email': 'email@address' },
    { $pull: { members: { email: 'email@address' } } },
    { multi: true }
)

1
你可以使用findOneAndUpdate$pull操作符来完成此任务。
要从文档数组中删除项目,可以查看MongoDbdocs
您需要使用awaitthen块进行查询。我使用了await,并通过添加async关键字使函数异步化。我们还需要一个空的查询对象。
我还添加了new:true选项,以返回更新后的对象以检查该项是否被删除。
您需要处理没有匹配文档的情况,我为您添加了一个TODO。
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 });
  }
};

它运行得很好!非常感谢!你为什么清空了查询对象?能否请你解释一下?我尝试过相同的解决方案,但我把这个查询放在了这里 => const query = {"members.email": email}; - Olavo Alexandrino
@OlavoAlexandrino 因为查询似乎用于顶级文档,所以在这种情况下必须为空。我猜你可以在答案的文档中找到更多信息。 - SuleymanSah

0
尝试使用update()方法和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 });
    }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接