我有一个用户模型,该模型使用一些属性创建,这些属性稍后会在用户激活后被删除。我注意到在用户发起forgetPassword请求后,这些属性重新出现。
当我单步执行代码(它是一个快速应用程序)时,我在forgetPassword控制器中有一个User.findOne请求,它返回一个仍然具有已删除属性的用户文档,因此它们会被保存回来数据库,当我保存密码重置令牌时。
function forgotPassword(req, res, next) {
const username = req.body.username;
// Generate token
const token = uuid.v4();
// Find the user
User.findOne({ username: username }, function(err, user) {
if (err) {
return next(err);
}
// At this stage user also has the properties that
// were previously deleted when I inspect it
user.resetToken = token;
user.save(function(err, savedUser, numAffected) {
// So resetToken gets saved but also the previously deleted properties
...
});
我在数据库中验证了他们在用户激活时被删除,然后在forgetPassword请求后重新显示。
Mongoose是否会对findOne请求进行某种缓存?
我查看了Mongoose github的问题并没有找到任何结果。 Mongoose findOne使用了mquery,但我无法看到缓存层。
如何让Mongoose使用数据库中的实时数据?
更新了最小的例子:
[更新:我没有在最小的例子中添加任何快速路线,但事件的顺序基本相同,但在实际的应用程序中,db调用分散在几个不同的快速路线上]
的package.json:
{
"name": "minimal-mongoose-findone-old-data-issue",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"chance": "^1.0.11",
"mongoose": "^4.12.4",
"uuid": "^3.1.0"
}
}
index.js:
const mongoose = require('mongoose');
const uuid = require('uuid');
const chance = new(require('chance'));
const dbPort = process.env.DBPORT;
const dbName = 'minimal-mongoose-findone-old-data-issue';
const mongoUrl = `mongodb://localhost:${dbPort}/${dbName}`;
mongoose.connect(mongoUrl, { user: '', pass: '' });
mongoose.set("debug",true);
const UserSchema = new mongoose.Schema({
username: {
type: String,
unique: true
},
activationToken: {
type: String,
default: uuid.v4()
},
active: {
type: Boolean,
default: false
},
passwordToken: {
type: String
}
}, { timestamps: true });
const User = mongoose.model('User', UserSchema);
// Create user
const username = chance.first();
const user = new User();
user.username = username;
user.save(function(err, savedUser) {
if (err) { throw err };
console.log(`STEP 1: user created: ${JSON.stringify(savedUser, 0, 2)}`);
// Activate user
User.findOne({
activationToken: savedUser.activationToken
}, function(err, foundUser) {
if (err) { throw err };
console.log(`STEP 2: user found: ${JSON.stringify(foundUser, 0, 2)}`);
foundUser.active = true;
foundUser.activationToken = undefined;
foundUser.save(function(err, activatedUser, numAffected) {
if (err) { throw err };
console.log(`STEP 3: user activated: ${JSON.stringify(activatedUser, 0, 2)}`);
// Reset password
User.findOne({
username: username,
}, function(err, resetPasswordUser) {
if (err) { throw err };
console.log(`STEP 4: user found for password reset: ${JSON.stringify(resetPasswordUser, 0, 2)}`);
// Password reset logic here etc...
// The problem is that since the second findOne call returns old data,
// the activationToken gets saved back to the database when I save resetPasswordUser
process.exit();
});
});
});
});
在STEP 3中,console.log输出没有activationToken
在STEP 4中,activationToken返回console.log输出
运行节点index.js的输出:[使用mongo调试输出更新]
Mongoose: users.insert({ updatedAt: new Date("Wed, 25 Oct 2017 08:02:48 GMT"), createdAt: new Date("Wed, 25 Oct 2017 08:02:48 GMT"), username: 'Hannah', _id: ObjectId("59f045287a2de871d0fbce14"), active: false, activationToken: 'c9048f36-02c7-4a0f-8e2c-abf5cb9120fe', __v: 0 })
STEP 1: user created: {
"__v": 0,
"updatedAt": "2017-10-25T08:02:48.107Z",
"createdAt": "2017-10-25T08:02:48.107Z",
"username": "Hannah",
"_id": "59f045287a2de871d0fbce14",
"active": false,
"activationToken": "c9048f36-02c7-4a0f-8e2c-abf5cb9120fe"
}
Mongoose: users.findOne({ activationToken: 'c9048f36-02c7-4a0f-8e2c-abf5cb9120fe' }, { fields: {} })
STEP 2: user found: {
"_id": "59f045287a2de871d0fbce14",
"updatedAt": "2017-10-25T08:02:48.107Z",
"createdAt": "2017-10-25T08:02:48.107Z",
"username": "Hannah",
"__v": 0,
"active": false,
"activationToken": "c9048f36-02c7-4a0f-8e2c-abf5cb9120fe"
}
Mongoose: users.update({ _id: ObjectId("59f045287a2de871d0fbce14") }, { '$unset': { activationToken: 1 }, '$set': { active: true, updatedAt: new Date("Wed, 25 Oct 2017 08:02:48 GMT") } })
STEP 3: user activated: {
"_id": "59f045287a2de871d0fbce14",
"updatedAt": "2017-10-25T08:02:48.153Z",
"createdAt": "2017-10-25T08:02:48.107Z",
"username": "Hannah",
"__v": 0,
"active": true
}
Mongoose: users.findOne({ username: 'Hannah' }, { fields: {} })
STEP 4: user found for password reset: {
"_id": "59f045287a2de871d0fbce14",
"updatedAt": "2017-10-25T08:02:48.153Z",
"createdAt": "2017-10-25T08:02:48.107Z",
"username": "Hannah",
"__v": 0,
"active": true,
"activationToken": "c9048f36-02c7-4a0f-8e2c-abf5cb9120fe"
}
在运行index.js后的mongo shell中:
MongoDB shell version: 3.2.4
connecting to: test
> use minimal-mongoose-findone-old-data-issue
switched to db minimal-mongoose-findone-old-data-issue
> db.users.find({ username: 'Hannah'}).pretty()
{
"_id" : ObjectId("59f045287a2de871d0fbce14"),
"updatedAt" : ISODate("2017-10-25T08:02:48.153Z"),
"createdAt" : ISODate("2017-10-25T08:02:48.107Z"),
"username" : "Hannah",
"active" : true,
"__v" : 0
}