简体   繁体   English

为什么我可以在MongoDB中更新一个字段,而不更新另一个字段? (MEAN Stack)

[英]Why can I update one field but not another in MongoDB? (MEAN Stack)

I have two fields: "password_hash" and "password_token" in my db.user mongoDB collection. 我的db.user mongoDB集合中有两个字段:“ password_hash”和“ password_token”。 I can update "password_hash" from API (curl, through an express route, into a mongoose model) but I can't update "password_token" using nearly the exact same code. 我可以从API更新“ password_hash”(通过快速路由,将其更新为猫鼬模型),但是我无法使用几乎完全相同的代码来更新“ password_token”。 I can modify either 'manually' from Studio3t, but that would defeat the purpose of writing an API. 我可以从Studio3t中“手动”修改其中任何一个,但这会破坏编写API的目的。 I also think that means this behavior is not related to indexes, validators, etc. on the database collection, since I'm allowed to save values in either field. 我还认为这意味着此行为与数据库集合上的索引,验证器等无关,因为允许在任何一个字段中保存值。 When I try to do the same from the API, I get no error message, only { ok: 0, n: 0, nModified: 0 } and no updated field. 当我尝试通过API执行相同操作时,没有收到错误消息,只有{ ok: 0, n: 0, nModified: 0 } ,也没有更新字段。

Here is the abbreviated document: 这是缩写的文档:

"username" : "user1", 
"password_hash" : "$2a$10$pVTT8FS.WV.sba1wvVwYMu7hMqaGkP1toJx5PGMXrl/ZnLyLtqsYy", 
"password_token" : ""

Here are the curl commands I'm using: 这是我正在使用的curl命令:

# curl -w '\n' -H "Content-Type: application/json" -X POST -d '{ "username": "user1"}' http://localhost:3000/users/save_hash
{"success":true,"message":"Saved a hash for user1."}

# curl -w '\n' -H "Content-Type: application/json" -X POST -d '{ "username": "user1"}' http://localhost:3000/users/reset_user
{"success":true,"message":"Saved a reset token for user1."}

...both return success, as written, but the second has no effect on the DB field "password_token". ...两者均按书面形式成功返回,但是第二个对DB字段“ password_token”没有影响。

Here are the structurally identical express routes: 以下是结构相同的快递路线:

router.post('/save_hash', (req, res, next) => {
    const username = req.body.username;
    User.getUserByUsername(username, (err, user) => {
        if (err) logger.error(err);
        if (user) {
            bcrypt.hash(user.password, 10, (err, hash) => {
                if (hash) {
                    User.saveHash(user.username, hash, err);
                    return res.json({success: true, message: 'Saved a hash for ' + user.username + '.'});
                }
            })
        }
    })
});

router.post('/reset_user', (req, res, next) => {
    const username = req.body.username;
    User.getUserByUsername(username, (err, user) => {
        if (err) logger.error(err);
        if (user) {
            crypto.randomBytes(20, (err, buffer) => {
                if (buffer) {
                    const token = buffer.toString('hex');
                    User.resetToken(user.username, 'test', err);
                    if (err) {logger.error(err) } else {
                        return res.json({success: true, message: 'Saved a reset token for ' + user.username + '.'});
                    }
                }
            });
        }
    })
});

And here are the structurally identical methods on the models: 这是模型上结构上相同的方法:

module.exports.saveHash = function (username, password_hash, callback) {
    const query = {'username': username};
    User.update(query, { $set: { 'password_hash': password_hash }}, (err_update, raw) => {
        if (err_update) { logger.error(err_update); } else {console.log('raw data: ', raw)}
    })
};

module.exports.resetToken = function (username, token, callback) {
    const query = {'username': username};
    User.update(query, { $set: { 'password_token': token}}, (err_update, raw) => {
        if (err_update) { logger.error(err_update); } else {console.log('raw data: ', raw)}
    })
};

The curl, route, and model for "password_hash" work as expected. “ password_hash”的卷曲,路由和模型按预期工作。 The same duplicated to update "password_token" do not work. 相同的副本来更新“ password_token”不起作用。 Even the following modifications work: 甚至可以进行以下修改:

module.exports.resetToken ...
User.update(query, { $set: { 'password_hash': token}}... // works. updates "password_hash" to the token value.

module.exports.resetToken ...
User.update(query, { $set: { 'password_hash': 'test'}}... // works. updates "password_hash" to 'test'.

...but if I modify saveHash(), which currently works to update "password_hash", so that it should instead "password_token", it does not modify "password_token": ...但是,如果我修改saveHash()(当前可用于更新“ password_hash”),使其改为“ password_token”,则不会修改“ password_token”:

module.exports.saveHash ...
User.update(query, { $set: { 'password_token': 'test'}}... /* Does not work. returns  { ok: 0, n: 0, nModified: 0 } ...and does not modify "password_token". */

...So it appears there is 'something wrong' with the password_token field itself, since I can update a different field with the exact same code. ...因此看来password_token字段本身存在“问题”,因为我可以使用完全相同的代码来更新其他字段。

For what it's worth: all the documentation I've read says I should be able to call update() on a field that does not yet exist and it will be created by an implicit $set, but I have not found that to be the case. 对于它的价值:我阅读的所有文档都说我应该能够在一个不存在的字段上调用update(),它将由一个隐式$ set创建,但是我没有发现它是案件。 I have had to create both "password_hash" and "password_token" using MongoShell before they can be updated: 我必须先使用MongoShell创建“ password_hash”和“ password_token”,然后才能进行更新:

db.users.update({},
  {$set : {"password_token":""}},
  {upsert:false,
  multi:true})

...so I wonder if I might be in version hell and I'm finally seeing a symptom. ...所以我想知道我是否可能在地狱版本中,最后看到了一个症状。

TL:DR; TL:DR; I can update one field "password_hash" just fine, but another field, "password_token" (and any additional fields I add) cannot be updated and return no error, using basically the same curl, route, and model method. 我可以很好地更新一个字段“ password_hash”,但是使用基本相同的curl,route和model方法,不能更新另一个字段“ password_token”(以及我添加的任何其他字段),也不会返回任何错误。 What gives? 是什么赋予了?

The simple answer, given by JohnnyHK, is that the new fields I'm creating in the DB were not also defined in my User schema. JohnnyHK给出的简单答案是,我在数据库中创建的新字段也未在用户模式中定义。

I have actually made this same mistake before. 我以前确实犯过同样的错误。 The lack of error and the only tip off being that the update operation failed means I need to tie a string around my finger any time I add a new field to a document. 没有错误,唯一的提示是更新操作失败,这意味着每当我向文档中添加新字段时,都需要在我的手指上绑一个字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Mongodb:我可以比较一个字段中的值是否包含在另一个字段中 - Mongodb: can I compare if value in one field is contained in another field 在MEAN堆栈中,如何做一次MongoDB索引? - In a MEAN stack, how can I do one-time MongoDB indexing? 如果复选框被选中,我如何使用平均堆栈中的复选框更新我的待办事项状态,它在 mongodb 数据库中为真,否则为假 - How i can update my todo status using checkbox in mean stack if check box is checked it place true in mongodb database otherwise false MEAN Stack无法使用PUT方法更新MongoDB记录 - MEAN Stack Cannot Update MongoDB Record using PUT method 如何在 Mean Stack (Node.js + Mongodb) 上的用户身份验证中检查当前登录的用户? - How can I check currently logged user in user authentication on Mean Stack (Node.js + Mongodb)? 均值堆栈:如何使用nodejs expressjs和angular 6在mongodb中存储图像? - Mean Stack: How can I store image in mongodb with nodejs expressjs and angular 6? 如何同时更新 MongoDB 记录中的同一字段? - How can i simultenously update the same field in a MongoDB Record? 无法将Mongodb连接到MEAN堆栈的Node.js - Can't connect Mongodb to Node.js, MEAN-stack Bitnami MEAN堆栈无法连接到本地mongoDb - Bitnami MEAN stack can't connect to local mongoDb 如何在MEAN堆栈中使用orientDB - How can I use orientDB in MEAN stack
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM