问题
Context: I have a Post Mongoose model that contains a csv_files array field to store csv strings. I make a fetch API request from a different web app to POST the csv strings for a particular Post.
The code below produces an error
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): VersionError: No matching document found for id "5966932399e969ad8013bedf"
router.js
router.post('/posts/:url/upload-csv/:csv_name', (req, res) => {
let csv_name = req.params.csv_name;
let csv_string = csv_name+req.body.csv_string;
Post.findOne({url: req.params.url})
.then((post) => {
if (post.csv_files.length === 0) {
post.csv_files.push(csv_string);
} else {
let foundExistingCSV = false;
for (var i = 0; i < post.csv_files.length; i++) {
if (post.csv_files[i].includes(csv_name)) {
foundExistingCSV = true;
post.csv_files[i] = csv_string;
break;
}
}
if (!foundExistingCSV) post.csv_files.push(csv_string);
}
post.markModified('csv_files');
post.save();
return res.status(200);
})
.catch((err) => {
console.log(err);
return res.status(400);
});
});
models/post.js
const mongoose = require('mongoose');
var stringPreset = {
type: String,
uppercase: true
}
var Post = mongoose.model('Post', {
name : stringPreset,
url : String,
password : String,
csv_files : { type : Array , "default" : [] },
updatedAt : { type: Date, default: Date.now }
});
module.exports = { Post };
How can I fix this so that the document saves into the csv_files array without the error?
回答1:
When saving an object to Mongo DB you have to understand that Mongo DB has a version control system in place. This helps ensure that if you save an object once, when saving it again you don't end up overwriting the previously saved data.
This is the error you're seeing. If you want to force the object to update regardless of version control in this particular instance you may want to use .update() instead. This will force the object to be updated regardless of its currently saved state.
This is because .save() watches and cares about version controls, while .update() will update the object regardless of version control.
回答2:
Looks like @robertklep was right. I fixed my issue by wrapping the first API call in a Promise and then executing the second API call after the first one completed.
I'll wait to mark this as the answer just in case anyone comes across a better solution.
回答3:
just to comment here what my problem apparently was.
Error Message:
message: 'No matching document found for id "5c86d3a15bbcb965d85d80d1" version 3', name: 'VersionError', version: 3
My code:
update: function (data) {
var session = new Session(data);
database.logging("INFO", "session-update", session.cid, session.order.orderNumber);
return new Promise(function (resolve, reject) {
session.save()
.then(savedSession => resolve(savedSession))
.catch(savedSessionError => reject(savedSessionError))
});
}
My parameter 'data' was already a Mongoose object and I was creating a new one and trying to save() it. So like @dacopenhagen said, save() checks the version of the document and it's throwing an VersionError error.
How I fixed it Just removing the creation of the Session() object. Removed this line
var session = new Session(data);
I hope this help.
来源:https://stackoverflow.com/questions/45223025/mongoose-version-error-no-matching-document-found-for-id