Методы Mongoose "статические" и методы "экземпляр"
Я считаю, что этот вопрос похож на этот, но терминология другая. Из документации Mongoose 4:
Мы также можем определить наши собственные методы экземпляра документа.
// define a schema
var animalSchema = new Schema({ name: String, type: String });
// assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function (cb) {
return this.model('Animal').find({ type: this.type }, cb);
}
Теперь все наши экземпляры животных имеют доступный метод findS SimilarTypes.
А потом:
Добавление статических методов в модель также просто. Продолжая с нашей животной схемой:
// assign a function to the "statics" object of our animalSchema
animalSchema.statics.findByName = function (name, cb) {
return this.find({ name: new RegExp(name, 'i') }, cb);
}
var Animal = mongoose.model('Animal', animalSchema);
Animal.findByName('fido', function (err, animals) {
console.log(animals);
});
Кажется, что для статических методов у каждого экземпляра животного был бы findByName
метод findByName
. Каковы объекты statics
и methods
в схеме? В чем разница и почему я должен использовать один над другим?
Ответы
Ответ 1
statics
- это методы, определенные в модели. methods
определены в документе (экземпляре).
Вы можете использовать статический метод, такой как Animal.findByName
:
const fido = await Animal.findByName('fido');
// fido => { name: 'fido', type: 'dog' }
И вы можете использовать метод экземпляра, например, fido.findSimilarTypes
:
const dogs = await fido.findSimilarTypes();
// dogs => [ {name:'fido',type:'dog} , {name:'sheeba',type:'dog'} ]
Но вы не Animals.findSimilarTypes()
выполнять Animals.findSimilarTypes()
потому что Animals - это модель, у нее нет "типа". findSimilarTypes
нужен this.type
который не существует в модели Animals, только экземпляр документа будет содержать это свойство, как определено в модели.
Точно так же вы wouldn't¹ сделать fido.findByName
, потому что findByName
нужно будет искать через все документы и fido
это просто документ.
"Ну, технически вы можете, потому что экземпляр имеет доступ к коллекции ( this.constructor
или this.model('Animal')
), но не имеет смысла (по крайней мере, в этом случае) иметь метод экземпляра, который не ' не использовать какие-либо свойства из экземпляра. (спасибо @AaronDufour за указание на это)
Ответ 2
Логика базы данных должна быть инкапсулирована в модель данных. Mongoose предоставляет 2 способа сделать это: методы и статика. Methods добавляет метод экземпляра к документам, тогда как Statics добавляет статические методы "класса" к самим моделям. Ключевое слово static определяет статический метод для модели. Статические методы не вызываются в экземплярах модели. Вместо этого они обращаются к самой модели. Часто это служебные функции, такие как функции для создания или клонирования объектов. как пример ниже:
const bookSchema = mongoose.Schema({
title: {
type : String,
required : [true, 'Book name required']
},
publisher : {
type : String,
required : [true, 'Publisher name required']
},
thumbnail : {
type : String
}
type : {
type : String
},
hasAward : {
type : Boolean
}
});
//method
bookSchema.methods.findByType = function (callback) {
return this.model('Book').find({ type: this.type }, callback);
};
// statics
bookSchema.statics.findBooksWithAward = function (callback) {
Book.find({ hasAward: true }, callback);
};
const Book = mongoose.model('Book', bookSchema);
export default Book;
для получения дополнительной информации: https://osmangoni.info/posts/separating-methods-schema-statics-mongoose/
Ответ 3
Просьба также проверить эту документацию от mongoosejs о документах и моделях
[https://mongoosejs.com/docs/documents.html][1]
это помогло мне лучше понять "статические" методы против методов "экземпляра"