Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose 'static' methods vs. 'instance' methods

I believe this question is similar to this one but the terminology is different. From the Mongoose 4 documentation:

We may also define our own custom document instance methods too.

// 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); } 

Now all of our animal instances have a findSimilarTypes method available to it.

And then:

Adding static methods to a Model is simple as well. Continuing with our animalSchema:

// 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); }); 

It seems with static methods each of the animal instances would have the findByName method available to it as well. What are the statics and methods objects in a Schema? What is the difference and why would I use one over the other?

like image 871
Startec Avatar asked Apr 16 '15 02:04

Startec


People also ask

What is the difference between statics and methods in Mongoose?

Methods operate on an instance of a model. Statics behave as helper functions only and can perform any action you want, including collection level searching. They aren't tied to an instance of a Model. But methods are also defined on models and work on all the instances of that model.

What are static methods in Mongoose?

mongoose Mongoose Schemas Schema Statics Schema Statics are methods that can be invoked directly by a Model (unlike Schema Methods, which need to be invoked by an instance of a Mongoose document). You assign a Static to a schema by adding the function to the schema's statics object.

Can you define methods in Mongoose schema?

Each Schema can define instance and static methods for its model.

What is the difference between instanced objects methods and static objects methods?

Instance method are methods which require an object of its class to be created before it can be called. Static methods are the methods in Java that can be called without creating an object of class.


2 Answers

statics are the methods defined on the Model. methods are defined on the document (instance).

You might use a static method like Animal.findByName:

const fido = await Animal.findByName('fido'); // fido => { name: 'fido', type: 'dog' } 

And you might use an instance method like fido.findSimilarTypes:

const dogs = await fido.findSimilarTypes(); // dogs => [ {name:'fido',type:'dog} , {name:'sheeba',type:'dog'} ] 

But you wouldn't do Animals.findSimilarTypes() because Animals is a model, it has no "type". findSimilarTypes needs a this.type which wouldn't exist in Animals model, only a document instance would contain that property, as defined in the model.

Similarly you wouldn't¹ do fido.findByName because findByName would need to search through all documents and fido is just a document.

¹Well, technically you can, because instance does have access to the collection (this.constructor or this.model('Animal')) but it wouldn't make sense (at least in this case) to have an instance method that doesn't use any properties from the instance. (thanks to @AaronDufour for pointing this out)

like image 187
laggingreflex Avatar answered Sep 19 '22 09:09

laggingreflex


Database logic should be encapsulated within the data model. Mongoose provides 2 ways of doing this, methods and statics. Methods adds an instance method to documents whereas Statics adds static “class” methods to the Models itself.The static keyword defines a static method for a model. Static methods aren't called on instances of the model. Instead, they're called on the model itself. These are often utility functions, such as functions to create or clone objects. like example below:

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; 

for more info: https://osmangoni.info/posts/separating-methods-schema-statics-mongoose/

like image 38
MR EXCEL Avatar answered Sep 21 '22 09:09

MR EXCEL