Mongoose:查找、修改、保存

IT技术 javascript node.js mongoose
2021-01-25 09:05:20

我有一个mongooseUser模型:

var User = mongoose.model('Users',
    mongoose.Schema({
        username: 'string',
        password: 'string',
        rights: 'string'
    })
);

我想找到User模型的一个实例,修改它的属性,然后保存更改。这是我尝试过的(这是错误的!):

User.find({username: oldUsername}, function (err, user) {
    user.username = newUser.username;
    user.password = newUser.password;
    user.rights = newUser.rights;

    user.save(function (err) {
        if(err) {
            console.error('ERROR!');
        }
    });
});

查找、修改和保存User模型实例的语法是什么

6个回答

user回调参数是一个带有find. 在查询单个实例时使用findOne而不是find

User.findOne({username: oldUsername}, function (err, user) {
    user.username = newUser.username;
    user.password = newUser.password;
    user.rights = newUser.rights;

    user.save(function (err) {
        if(err) {
            console.error('ERROR!');
        }
    });
});
@DeLac 不,save在这种情况下执行更新操作。
2021-03-17 09:05:20
非常重要的提示。有时我必须.markModified在保存之前在文档上使用如果我不这样做,更改将不会保存到数据库中。mongoosejs.com/docs/schematypes.html#usage-notes
2021-03-25 09:05:20
@DeLac,您可能会在保存 User 时看到重复键错误_id在这种情况下,尝试单独更新属性或_id在 之前先删除save
2021-04-08 09:05:20
我无法删除 _id,因为其他对象引用了它。如果我删除它,我猜 mongo 会为它选择另一个 _id。更新不执行预存功能。我不知道 save() 如果应用于现有对象,则更新它。我不确定 mongo 如何知道它何时是更新,而何时使用现有 _id 保存新对象是非法尝试
2021-04-10 09:05:20
@DeLac Mongoose 通过isNewMongoose 文档实例上的属性跟踪它
2021-04-10 09:05:20

为什么不使用Model.update毕竟,除了更新其属性之外,您不会将找到的用户用于其他任何用途:

User.update({username: oldUsername}, {
    username: newUser.username, 
    password: newUser.password, 
    rights: newUser.rights
}, function(err, numberAffected, rawResponse) {
   //handle it
})
请注意,Model.update 没有通过 Schema 中定义的验证!见第一段:mongoosejs.com/docs/validation.html
2021-03-31 09:05:20
是的,但是因为“Model.update 将命令直接发送到 MongoDB - 文档没有返回 - 所以没有什么可以运行验证” - Aaron Heckmann github.com/LearnBoost/mongoose/issues/635
2021-04-13 09:05:20

findOne,修改字段并保存

User.findOne({username: oldUsername})
  .then(user => {
    user.username = newUser.username;
    user.password = newUser.password;
    user.rights = newUser.rights;

    user.markModified('username');
    user.markModified('password');
    user.markModified('rights');

    user.save(err => console.log(err));
});

findOneAndUpdate

User.findOneAndUpdate({username: oldUsername}, {$set: { username: newUser.username, user: newUser.password, user:newUser.rights;}}, {new: true}, (err, doc) => {
    if (err) {
        console.log("Something wrong when updating data!");
    }
    console.log(doc);
});

另见updateOne

我想补充一些非常重要的东西。我经常使用 JohnnyHK 方法,但我注意到有时更改不会保留到数据库中。当我使用.markModified它时,它起作用了。

User.findOne({username: oldUsername}, function (err, user) {
   user.username = newUser.username;
   user.password = newUser.password;
   user.rights = newUser.rights;

   user.markModified(username)
   user.markModified(password)
   user.markModified(rights)
    user.save(function (err) {
    if(err) {
        console.error('ERROR!');
    }
});
});

在保存之前使用 doc.markModified('pathToYourDate') 告诉mongoose有关更改。

如果您想使用find,就像我想在客户端进行的任何验证一样。

find 返回一个 ARRAY 对象

findOne 只返回一个对象

添加user = user[0]使保存方法对我有用。

这是你把它放的地方。

User.find({username: oldUsername}, function (err, user) {
    user = user[0];
    user.username = newUser.username;
    user.password = newUser.password;
    user.rights = newUser.rights;

    user.save(function (err) {
        if(err) {
            console.error('ERROR!');
        }
    });
});
建议不要在服务器上进行验证是一个可怕的建议。
2021-03-23 09:05:20
@VtoCorleone OP 的问题不是验证,而是访问。一旦您有权访问该对象,您就可以自由地围绕它编写任何逻辑,无论是验证还是修改。
2021-04-12 09:05:20