Mongoose 'static' 方法与 'instance' 方法
Mongoose 'static' methods vs. 'instance' methods
我认为这个问题类似于 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.
然后:
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);
});
使用静态方法似乎每个动物实例都可以使用 findByName
方法。架构中的 statics
和 methods
对象是什么?有什么区别,为什么我要用一个而不是另一个?
statics
是模型上定义的方法。 methods
在文档(实例)上定义。
您可以使用 static 方法,例如 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是一个模型,它没有"type"。 findSimilarTypes
需要 Animals 模型中不存在的 this.type
,只有文档实例会包含模型中定义的 属性。
同样,您不会¹执行 fido.findByName
,因为 findByName
需要搜索所有文档,而 fido
只是 a 文档。
¹好吧,从技术上讲,您 可以 ,因为实例确实可以访问集合(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 指出了这一点)
数据库逻辑应该封装在数据模型中。 Mongoose 提供了两种方法,方法和静态。 Methods 向文档添加实例方法,而 Statics 向 Models 添加静态“class”方法 itself.The 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/
对我来说,这并不意味着通过在 'static' 甚至 'instance' 关键字前面添加 Mongoose 来添加任何内容。
我认为 static 的含义和目的在任何地方都是相同的,即使对于外来语言或某种表示模型的驱动程序也是如此,用于像另一种面向对象编程一样构建块。例如也一样。
来自维基百科:
面向对象编程 (OOP) 中的方法 是与消息和对象关联的过程。对象由数据和行为组成。数据和行为包含一个接口,该接口指定对象如何被对象的各种消费者[1]中的任何一个使用。
数据表示为对象的属性,行为表示为对象的方法。例如,一个 Window 对象可以有打开和关闭等方法,而它的状态(在任何给定时间点是打开还是关闭)将是 属性。
静态方法 旨在与 class 的所有实例相关,而不是与任何特定实例相关。从这个意义上说,它们类似于静态变量。一个例子是静态方法,用于对 class 的每个实例的所有变量的值求和。例如,如果有一个产品 class,它可能有一个静态方法来计算所有产品的平均价格。
Math.max(双a,双b)
此静态方法没有所属对象,也不 运行 实例。它从其参数接收所有信息。[7]
即使不存在 class 的实例,也可以调用静态方法。静态方法被称为 "static" 是因为它们是在编译时根据它们被调用的 class 解析的,而不是像实例方法那样动态解析的,实例方法是基于 [=48= 多态解析的]对象的时间类型。
- 对
static
方法使用 .statics
。
- 对
instance
方法使用 .methods
。
//instance method
bookSchema.methods.findByType = function (callback) {
return this.model('Book').find({ type: this.type }, callback);
};
// static method
bookSchema.statics.findBooksWithAward = function (callback) {
Book.find({ hasAward: true }, callback);
};
statics
与 methods
几乎相同,但允许定义直接存在于模型中的函数。
statics
属于 Model 并且 methods
属于 Instance
Static methods
适用于定义它们的整个模型,而 instance methods
仅适用于集合中的特定文档。
this
在静态方法的上下文中 returns 整个模型,而 this
在实例方法的上下文中 returns 文档。
举个例子:
const pokemon = new mongoose.Schema({})
pokemon.statics.getAllWithType = function(type){
// Query the entire model and look for pokemon
// with the same type
// this.find({type : type})
}
pokemon.methods.sayName = function(){
// Say the name of a specific pokemon
// console.log(this.name)
}
const pokemonModel = mongoose.model('schema', pokemon)
const squirtle = new pokemonModel({name : "squirtle"})
// Get all water type pokemon from the model [static method]
pokemonModel.getAllWithType("water")
// Make squirtle say its name [instance method]
squirtle.sayName()
大家都说了,对单个文档进行操作时使用方法,对整个集合进行操作时使用静态。但是为什么呢?
比方说,我们有一个架构:
var AnimalSchema = new Schema({
name: String,
type: String
});
现在如文档中所述,if 您需要检查数据库中特定 document 的相似类型
你可以这样做:
AnimalSchema.methods.findSimilarType = function findSimilarType (cb) {
return this.model('Animal').find({ type: this.type }, cb);
};
现在,这里的this指的是文档本身。那么,这意味着,这份文件
不知道它属于哪个模型,因为 methods 默认与模型无关,它仅针对特定文档 obj。
但是我们可以让它与模型一起工作,使用this.model('anyModelName').
现在为什么要用方法来寻找相似种类的动物呢?
为了找到相似类型的动物,我们必须有一个动物对象,我们将为其找到相似类型的动物。
我们拥有的那个动物对象让我们说:
const Lion = await new Animal({name: Lion, type:"dangerous"});
接下来,当我们找到相似类型时,我们首先需要 Lion 对象,我们必须 拥有它。
很简单,每当我们需要特定 obj/document 的帮助来做某事时,我们都会使用方法。
现在碰巧我们还需要整个模型来搜索更苗条的类型,
尽管 它不能直接在方法中使用(记住 this.modelName 将 return 未定义)。我们可以通过将 this.model() 设置为我们的首选模型来获得它,在本例中为 Animal。
这就是所有的方法。
现在,statics 可以使用整个模型。
1)假设你想计算所有动物的总 price(假设模型有一个价格字段)你将使用静态 [因为你不需要任何特定的 Animal obj , 所以我们不会使用方法]
2)你想找到有黄色皮肤的动物(假设模型有一个皮肤场),你将使用静力学。 [为此我们不需要任何特定的 Animal obj,所以我们不会使用方法]
例如:
AnimalSchema.statics.findYellowSkin = function findSimilarType (cb) {
return this.find({ skin: "yellow" }, cb);
};
请记住,在方法中 this 引用模型,因此 this.modelName 将 return 动物(在我们的例子中)。
但就像方法一样,这里我们也可以(但我们不需要)设置模型使用。
AnimalSchema.methods.findSimilarType = function findSimilarType (cb) {
return this.model('Animal').find({ skin: "yellow" }, cb); //just like in methods
};
所以你可以看到静态和方法都非常相似。
Whenever you have a document and you need something to do with that,
use methods. Whenever you need to do something with the whole
model/collection, use statics.
我认为这个问题类似于 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.
然后:
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);
});
使用静态方法似乎每个动物实例都可以使用 findByName
方法。架构中的 statics
和 methods
对象是什么?有什么区别,为什么我要用一个而不是另一个?
statics
是模型上定义的方法。 methods
在文档(实例)上定义。
您可以使用 static 方法,例如 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是一个模型,它没有"type"。 findSimilarTypes
需要 Animals 模型中不存在的 this.type
,只有文档实例会包含模型中定义的 属性。
同样,您不会¹执行 fido.findByName
,因为 findByName
需要搜索所有文档,而 fido
只是 a 文档。
¹好吧,从技术上讲,您 可以 ,因为实例确实可以访问集合(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
数据库逻辑应该封装在数据模型中。 Mongoose 提供了两种方法,方法和静态。 Methods 向文档添加实例方法,而 Statics 向 Models 添加静态“class”方法 itself.The 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/
对我来说,这并不意味着通过在 'static' 甚至 'instance' 关键字前面添加 Mongoose 来添加任何内容。
我认为 static 的含义和目的在任何地方都是相同的,即使对于外来语言或某种表示模型的驱动程序也是如此,用于像另一种面向对象编程一样构建块。例如也一样。
来自维基百科: 面向对象编程 (OOP) 中的方法 是与消息和对象关联的过程。对象由数据和行为组成。数据和行为包含一个接口,该接口指定对象如何被对象的各种消费者[1]中的任何一个使用。
数据表示为对象的属性,行为表示为对象的方法。例如,一个 Window 对象可以有打开和关闭等方法,而它的状态(在任何给定时间点是打开还是关闭)将是 属性。
静态方法 旨在与 class 的所有实例相关,而不是与任何特定实例相关。从这个意义上说,它们类似于静态变量。一个例子是静态方法,用于对 class 的每个实例的所有变量的值求和。例如,如果有一个产品 class,它可能有一个静态方法来计算所有产品的平均价格。
Math.max(双a,双b)
此静态方法没有所属对象,也不 运行 实例。它从其参数接收所有信息。[7]
即使不存在 class 的实例,也可以调用静态方法。静态方法被称为 "static" 是因为它们是在编译时根据它们被调用的 class 解析的,而不是像实例方法那样动态解析的,实例方法是基于 [=48= 多态解析的]对象的时间类型。
- 对
static
方法使用.statics
。 - 对
instance
方法使用.methods
。
//instance method
bookSchema.methods.findByType = function (callback) {
return this.model('Book').find({ type: this.type }, callback);
};
// static method
bookSchema.statics.findBooksWithAward = function (callback) {
Book.find({ hasAward: true }, callback);
};
statics
与 methods
几乎相同,但允许定义直接存在于模型中的函数。
statics
属于 Model 并且 methods
属于 Instance
Static methods
适用于定义它们的整个模型,而 instance methods
仅适用于集合中的特定文档。
this
在静态方法的上下文中 returns 整个模型,而 this
在实例方法的上下文中 returns 文档。
举个例子:
const pokemon = new mongoose.Schema({})
pokemon.statics.getAllWithType = function(type){
// Query the entire model and look for pokemon
// with the same type
// this.find({type : type})
}
pokemon.methods.sayName = function(){
// Say the name of a specific pokemon
// console.log(this.name)
}
const pokemonModel = mongoose.model('schema', pokemon)
const squirtle = new pokemonModel({name : "squirtle"})
// Get all water type pokemon from the model [static method]
pokemonModel.getAllWithType("water")
// Make squirtle say its name [instance method]
squirtle.sayName()
大家都说了,对单个文档进行操作时使用方法,对整个集合进行操作时使用静态。但是为什么呢?
比方说,我们有一个架构:
var AnimalSchema = new Schema({
name: String,
type: String
});
现在如文档中所述,if 您需要检查数据库中特定 document 的相似类型 你可以这样做:
AnimalSchema.methods.findSimilarType = function findSimilarType (cb) {
return this.model('Animal').find({ type: this.type }, cb);
};
现在,这里的this指的是文档本身。那么,这意味着,这份文件 不知道它属于哪个模型,因为 methods 默认与模型无关,它仅针对特定文档 obj。 但是我们可以让它与模型一起工作,使用this.model('anyModelName').
现在为什么要用方法来寻找相似种类的动物呢?
为了找到相似类型的动物,我们必须有一个动物对象,我们将为其找到相似类型的动物。 我们拥有的那个动物对象让我们说: const Lion = await new Animal({name: Lion, type:"dangerous"}); 接下来,当我们找到相似类型时,我们首先需要 Lion 对象,我们必须 拥有它。 很简单,每当我们需要特定 obj/document 的帮助来做某事时,我们都会使用方法。
现在碰巧我们还需要整个模型来搜索更苗条的类型, 尽管 它不能直接在方法中使用(记住 this.modelName 将 return 未定义)。我们可以通过将 this.model() 设置为我们的首选模型来获得它,在本例中为 Animal。 这就是所有的方法。
现在,statics 可以使用整个模型。 1)假设你想计算所有动物的总 price(假设模型有一个价格字段)你将使用静态 [因为你不需要任何特定的 Animal obj , 所以我们不会使用方法] 2)你想找到有黄色皮肤的动物(假设模型有一个皮肤场),你将使用静力学。 [为此我们不需要任何特定的 Animal obj,所以我们不会使用方法]
例如:
AnimalSchema.statics.findYellowSkin = function findSimilarType (cb) {
return this.find({ skin: "yellow" }, cb);
};
请记住,在方法中 this 引用模型,因此 this.modelName 将 return 动物(在我们的例子中)。
但就像方法一样,这里我们也可以(但我们不需要)设置模型使用。
AnimalSchema.methods.findSimilarType = function findSimilarType (cb) {
return this.model('Animal').find({ skin: "yellow" }, cb); //just like in methods
};
所以你可以看到静态和方法都非常相似。
Whenever you have a document and you need something to do with that, use methods. Whenever you need to do something with the whole model/collection, use statics.