2016-12-03 48 views
3

如何在saveupdate貓鼬鉤/中間件中獲取特定型號的文檔計數?獲取貓鼬鉤鉤的型號數

考慮到thisupdate鉤查詢,這個效果很好:

schema.pre('update', function (next) { 
    this.model.count().then... 
}); 

save鉤這個

schema.pre('save', function (next) { 
    this.count().then... 
}); 

結果

this.count不是功能

當調試回調,thissave鉤和this.modelupdate鉤似乎是 '模型'(的Model實例)。他們之間有什麼區別?

爲什麼模型實例在save掛鉤錯過count方法?如何統一這兩個回調來獲取文檔數量?

我寧願堅持this而不是硬編碼模型,因爲這樣可以方便地使用ES6類進行模式繼承。

回答

5

其實this.model不會爲(預先保存鉤/中間件pre.('save'this.model會爲updatefindOneAndUpdate預掛鉤工作..等

pre.('save'掛鉤工作,你需要使用this.constructor代替this.model like:this.constructor.countthis.constructor.findOne

在我的例子假設創建模式國家

,所以你可以用這樣的波紋管:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var CountrySchema = new Schema({ 
    name: String, 
    //.... 
}); 

CountrySchema.pre('save', function(next) { 
    var self = this; 
    self.constructor.count(function(err, data) { 
    if(err){ 
     return next(err); 
    } 
    // if no error do something as you need and return callback next() without error 
    console.log('pre save count==', data); 
    return next(); 
    }); 
}); 

CountrySchema.pre('update', function (next) { 
    var self = this; 
    self.model.count(function(err, data) { 
    if(err){ 
     return next(err); 
    } 
    // if no error do something as you need and return callback next() without error 
    console.log('pre update count===', data); 
    return next(); 
    }); 
}); 

module.exports = mongoose.model('Country', CountrySchema); 

OR

可以使用mongoose.models['modelName']像:mongoose.models['Country'].count()例如

CountrySchema.pre('save', function(next) { 
    mongoose.models['Country'].count(function(err, data) { 
    if(err){ 
     return next(err); 
    } 
    console.log('pre save count==', data); 
    return next(); 
    }); 
}); 

CountrySchema.pre('update', function (next) { 
    mongoose.models['Country'].count(function(err, data) { 
    if(err){ 
     return next(err); 
    } 
    console.log('pre update count===', data); 
    return next(); 
    }); 
}); 

N.B:爲什麼this.model不能在save的預掛鉤中工作?

Middleware(也稱爲前後鉤子)是在執行異步功能期間通過控制傳遞的函數。

在貓鼬有2種類型的中間件:

  1. 文獻中間件和
  2. 查詢中間件
  1. 文獻中間件被支持函數。

    initvalidatesaveremove

  2. 查詢中間件被支持函數。

    countfindfindOnefindOneAndRemovefindOneAndUpdateinsertManyupdate

在貓鼬查詢中間件this.model是生成由貓鼬定義模型/實例。在這個中間件this返回所有實例變量,由貓鼬定義。

,其中在文檔中間件this回報所有領域您通過貓鼬所以this.model不是你定義的屬性定義不是。對於上面的例子,我有name屬性,所以你可以通過this.name得到那個將顯示你的請求值。但是,當使用this.contructor時,您將返回實例變量,這些變量由貓鼬定義,如返回Model實例變量。

+0

只要可能,我寧願堅持'this'。感謝您指向'this.constructor'。實際上,'count'應該是靜態方法,所以這是有道理的。我想這可能的解釋是它是'this.model'突出,它看起來像是Model的構造函數,而不是一個實例(屬性名稱中的錯誤情況不起作用)。 – estus

+0

添加了一些解釋,據我所知你可以看到@estus –

+0

非常感謝,這是相當詳盡的答案。 – estus

1

您可以使用模型變量的名稱而不是this

var mongoose = require('mongoose'); 
mongoose.connect('mongodb://localhost/test'); 

var schema = new mongoose.Schema; 
schema.add({ name: 'string' }); 

var Cat = mongoose.model('Cat', schema); 

schema.pre('save', function (next) { 
    Cat.count(function (err, count) { 
    if (err) { 
     console.log(err) 
    } else { 
     console.log('there are %d kittens', count); 
    } 
    next(); 
    }); 
}) 

var kitty = new Cat({ name: 'Zildjian' }); 
kitty.save(function (err) { 
    if (err) { 
    console.log(err); 
    } else { 
    console.log('meow'); 
    } 
}); 

後續執行報告正確的計數,然後執行保存操作。

$ node index.js 
there are 0 kittens 
meow 
$ node index.js 
there are 1 kittens 
meow 
$ node index.js 
there are 2 kittens 
meow 
$ node index.js 
there are 3 kittens 
meow 

而文檔正在數據庫中持久化。

db.cats.find() 
{ "_id" : ObjectId("5873b77454fc2a49fd7ec6cf"), "name" : "Zildjian", "__v" : 0 } 
{ "_id" : ObjectId("5873b777c051094a0ad5dda2"), "name" : "Zildjian", "__v" : 0 } 
{ "_id" : ObjectId("5873b7789aad6e4a15018ee8"), "name" : "Zildjian", "__v" : 0 } 
{ "_id" : ObjectId("5873b77b7628684a24c90b07"), "name" : "Zildjian", "__v" : 0 }