javascript - Mongoose 更新嵌套值

标签 javascript node.js mongodb mongoose

我的 mogoose 架构上有一些嵌套属性,如下所示:

const userSchemaValues = {
    username: {
        type: String,
        required: [true, 'Username required'],
        trim: true,
        unique: true,
        lowercase: true
    },
    password: {
        type: String,
        required: [true, 'Password required'],
        trim: true,
        minlength: 8
    },
  
 ...
  
    prop: {
        prop_1: String,
        prop_2: String
    }
};

valuesToUpdate.prop = _.pick(req.body, 'prop_1', 'prop_2');
	log.debug(JSON.stringify(valuesToUpdate));

	User.update({_id: req.params.id}, {$set: valuesToUpdate})
		.then((data) => {
			return res.json({message: data});
		})
		.catch(err => {
			log.error(err);
			return next({message: 'Error updating User.'});
		});

但是当我对使用这样的对象设置 prop_1 和 _2 的用户执行 User.update({_id: req.params.id}, {$set:valuesToUpdate}) 时 ({"prop":{"prop_1": "somevalue"}),它并不是寻找 prop 中的内容,而是覆盖它。我怎样才能避免这个问题?

最佳答案

您的查找需要包含要更新的属性。此外,更新语句需要 Positional Update Operator将其更改为(超出我的想象):

valuesToUpdate.prop = _.pick(req.body, 'prop_1', 'prop_2');
    log.debug(JSON.stringify(valuesToUpdate));

    User.update({$and : [{_id: req.params.id}, {prop.prop1 : "%oldvalue%"}]}, {$set: { "prop.$.prop1" : "%newvalue""}})
        .then((data) => {
            return res.json({message: data});
        })
        .catch(err => {
            log.error(err);
            return next({message: 'Error updating User.'});
        });

请注意,位置更新仅更新第一个出现的位置!

更新:重读你的问题后,我发现 props 不是数组......非常抱歉。 幸运的是,这使得事情变得更容易:)

您不需要该字段出现在查找中 对于集合:{$set:{“prop.prop1”:“newvalue”} 另外,位置更新不是必需的,因为它不是数组。

这使得以下结果:

valuesToUpdate.prop = _.pick(req.body, 'prop_1', 'prop_2');
log.debug(JSON.stringify(valuesToUpdate));

User.update({_id: req.params.id}, {$set: { "prop.prop1" : "%newvalue%"}})
    .then((data) => {
        return res.json({message: data});
    })
    .catch(err => {
        log.error(err);
        return next({message: 'Error updating User.'});
    });

UPDATE2:有关更新语句的更多信息。

由于评论,我将澄清更新命令。 当您想要更新文档中的字段时,您可以使用 $set命令。 这会更新一个或多个字段。 当您想更新多个字段时,可以使用以下命令来完成:

$set : { "prop.prop1" : "newvalueforprop1", "prop.prop2" : "newvalueforprop2"} }

但是当您使用上面的命令并指定一个字段时,它会生成如下命令:

$set : { "prop.prop1" : "newvalueforprop1", "prop.prop2" : null} }

这就是关于如何创建更新命令的全部内容。当您不知道它是 1 个还是 2 个属性时,您需要更新代码,以便它动态生成命令。 但您可以做的另一件事是让 mongoose 处理更新。

使用类似的东西:

User.findById(req.params.id, function (err, user) {
        if (err) {
            handleError(err)
        }
        else {
            //you should to some checking if the supplied value is present (!= undefined) and if it differs from the currently stored one
            user.prop.prop1 = "your value";
            user.prop.prop1 = "2nd value"

            user.save(function (err) {
                if (err) {
                    handleError(err)
                }
                else {
                    res.json(user);
                }
            });
        }
    });

希望现在一切都清楚了。

关于javascript - Mongoose 更新嵌套值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39408863/

相关文章:

javascript - meteor 类别和子类别选择菜单

node.js - 无法在 Ubuntu 20 上安装 'node-sass'

javascript - 如何在 Electron 浏览器窗口中查看 PDF?

javascript - 如何从 gulp-contains 回调中提取文件名?

mongodb - 跳过 mongo 上限集合

java - 错误 Appenders 包含无效元素或属性 "NoSql"

javascript - 如何避免困惑的嵌套 if-else 或 switch

PHP IF 条件内的 Javascript 反向链接代码

javascript - Ajax 在页面加载时触发

mysql - 如何基于Node.js为书店制作正确的BD