Подтвердить что ты не робот

Методы 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 в схеме? В чем разница и почему я должен использовать один над другим?

4b9b3361

Ответ 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]

это помогло мне лучше понять "статические" методы против методов "экземпляра"