findOneAndUpdate (mongoose) 返回 true 以更新模型中的嵌套文档,但没有更新

Posted

技术标签:

【中文标题】findOneAndUpdate (mongoose) 返回 true 以更新模型中的嵌套文档,但没有更新【英文标题】:findOneAndUpdate (mongoose) returns true for updating a nested document in a model but nothing is updated 【发布时间】:2020-06-25 02:50:14 【问题描述】:

是的,我知道还有非常相似的其他问题,我正在研究它们,但不幸的是,我找不到解决方案。所以,我正在尝试使用“findOneAndUpdate”方法更新猫鼬模型中的嵌套文档,但即使它返回一个文档,这个文档也是原始文档,而不是更新文档。

下面是模型:

var mongoose = require('mongoose');

var teamMemberModelSchema = new mongoose.Schema(
    "_id": mongoose.SchemaTypes.ObjectId,
    "email": 
        "type": String,
        "required": true,
        "min": 5,
        "max": 20
    ,
    "name": 
        "type": String,
        "required": true,
        "min": 5,
        "max": 20
    ,
    "role": 
        "type": String,
        "required": true,
        "min": 20,
        "max": 50
    ,
    "twitter": 
        "type": String,
        "required": true,
        "min": 20,
        "max": 50
    ,
    "facebook": 
        "type": String,
        "required": true,
        "min": 20,
        "max": 50
    ,
    "linkedin": 
        "type": String,
        "required": true,
        "min": 20,
        "max": 50
    ,
);

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

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

我想使用以下代码 sn-p 更新成员嵌套文档:

module.exports.teamMemberUpdate = function (req, res) 

    var email = req.body.email;
    var name = req.body.name;
    var role = req.body.role;
    var twitter = req.body.twitter;
    var facebook = req.body.facebook;
    var linkedin = req.body.linkedin;

    teamFunctions.findTeamMember(email)
        .then(data => 

            if (data.length === 0) 
                responseUtilities.sendJSON(res, false,  "message": teamMsg.teamMemberNotFound );
            
            else 
                return data[0];
            

        )
        .then(() => 

            const query =  "members.email": email ;
            const options =  new: true ;
            var update = 
                $set: 
                    email: email,
                    name: name,
                    role: role,
                    twitter: twitter,
                    facebook: facebook,
                    linkedin: linkedin
                
            ;

            TeamModel.findOneAndUpdate(query, update, options, function (err, result) 
                var message = teamMsg.teamMemberUpdatedSuccess;
                if (!result) 
                    message = teamMsg.teamMemberUpdatedError;
                
                responseUtilities.sendJSON(res, err,  "message": message );
            );

        )
        .catch(err => 
            console.log(err.message);
            responseUtilities.sendJSON(res, err,  "message": err.message );
        );


显示“teamMemberUpdatedSuccess”值,但实际上并没有更新原文档。

谁能找出问题出在哪里?

【问题讨论】:

【参考方案1】:

TeamModel 没有任何名为emailname 等的属性(请参阅您的更新变量)。您的更新查询应如下所示:

const update = 
  $set: 
    'members.$.email': email
  
;

$ 很重要,因为members 是一个数组。

希望对你有帮助。

【讨论】:

【参考方案2】:

您可以使用带点符号的位置 $ 运算符。 Here 是您的场景的文档。

您可以使用以下功能使用给定的电子邮件更新成员。如您所见,我们只有一个数据库访问权限。不需要使用teamFunctions.findTeamMember函数。

我使用了一些现代 javascript 功能,例如 object destructuring 和 async/await 语法来编写干净的代码。

module.exports.teamMemberUpdate = async function(req, res) 
  const  email, name, role, twitter, facebook, linkedin  = req.body;

  const query = 
    "members.email": email
  ;

  const options =  new: true ;
  const update = 
    $set: 
      "members.$.email": email,
      "members.$.name": name,
      "members.$.role": role,
      "members.$.twitter": twitter,
      "members.$.facebook": facebook,
      "members.$.linkedin": linkedin
    
  ;

  try 
    const result = await TeamModel.findOneAndUpdate(query, update, options);

    if (!result) 
      return res.status(400).send("No member found for the email");
    
    res.send(result);
   catch (err) 
    console.log(err);
    res.status(500).send("Something went wrong");
  
;

请先尝试使用此功能而不做任何更改,在您看到它有效后,您可以进行特定于应用程序的更改。

我还注意到您的架构定义中有一个小问题,您应该使用 minlenghtmaxlength 选项作为字符串类型,而不是 minmax

【讨论】:

以上是关于findOneAndUpdate (mongoose) 返回 true 以更新模型中的嵌套文档,但没有更新的主要内容,如果未能解决你的问题,请参考以下文章

如何在mongo中进行索引后findOneAndUpdate()的性能评估

Mongoose findOneAndUpdate 更新多个字段

Mongoose - 使用 findOneAndUpdate 更新子文档

findOneAndUpdate的用法详解

findOneAndUpdate 最新文档

findOneAndUpdate() 基于查找查询条件的子数组