我正試圖創建一個「findOneAndUpdate」查詢來啓動預驗證中間件。預驗證中間件後創建或更新字段?
需要這些中間件來驗證給定的座標並在請求的主體中未提供時創建'id'字段(是的,而不是的'_id')。
正如您在下面看到的(請參閱代碼中的註釋),我很接近,但不明白爲什麼mongo
引發的錯誤是重複密鑰變體。
也許承諾不是去這裏的方式,雖然他們讓我來實現方式比鏈接pre
中間件。
這裏是我的快遞路線:
/* POST /geolocs */
router.post('/', function(req, res, next) {
Geoloc.create(req.body, function(err, post) {
if (err) return next(err);
res.status(201).json(post);
});
});
這裏是我的架構:
var GeolocSchema = new mongoose.Schema({
id: {
type: String,
required: true,
unique: true
},
location: {
type: {
type: String,
default: 'Point',
required: true
},
coordinates: {
type: [Number],
required: true
}
},
count: Number
});
GeolocSchema.index({
location: '2dsphere'
});
預驗證的中間件:
// Before validation, check given coordinates for errors.
GeolocSchema.pre('validate', function(next) {
coord = this.location.coordinates
if (this.location.type && coord) {
if (Array.isArray(coord) && coord.length === 2) {
lat = coord[1];
lon = coord[0];
if ((-90 <= lat && lat <= 90) && (-180 <= lat && lat <= 180)) next();
}
}
var err = new Error('...'); // Long error text, irrelevant here
err.status = 400;
next(err);
});
// Then, if no 'id' is given, create it.
GeolocSchema.pre('validate', function(next) {
if (!this.id) {
strLat = this.location.coordinates[1].toFixed(3).replace('.', '_');
strLon = this.location.coordinates[0].toFixed(3).replace('.', '_');
this.id = strLat + '-' + strLon;
}
next();
});
我很想能夠做的就是添加低於上述以下幾點:
// Here, using the validate or save hook doesn't change anything.
GeolocSchema.pre('validate', function(next) {
var prom = Geoloc.findOne({
'id': {
$eq: this.id
}
}).exec();
prom.then((err, geoloc) => { // Arrow function here to access 'this'
if (err) next(err);
// If no geoloc was found, go ahead and save.
if (!geoloc) next();
// Else, update to increment the count (THIS WORKS).
return Geoloc.update({'id': this.id}, {$inc: {count: 1}}).exec();
}).then((toto) => {
// This doesn't work, the error thrown by mongo is a duplicate key error (E11000).
if (toto) next(new Error('204'));
else next(new Error("Something that shouldn't happen, happened..."));
});
});
是的,我知道。很確定我已經閱讀了幾乎所有關於這個主題的文檔:-D但是,爲了執行'find'操作,我需要在預驗證步驟中構建的'id' ...或者我錯過了什麼? – Gormador
另外,我認爲確實有一個'更新'鉤子。請參閱[這裏](http://mongoosejs.com/docs/middleware.html#notes)。 – Gormador
是的,但是如果你在給出的Github鏈接上閱讀了這個問題,開發人員有一個評論說,更新的鉤子不是他們的。最好的嘗試看看。如果它有效,它就在那裏。如果沒有,那麼麻煩就開始了! :-) –