Mongoose'静态'方法与'实例'方法

时间:2015-04-16 02:49:20

标签: node.js mongodb mongoose

我认为这个问题与this one类似,但术语不同。来自Mongoose 4 documentation

  

我们也可以定义自己的自定义文档实例方法。

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

现在我们所有的动物实例都有一个findSimilarTypes方法。

然后:

  

向模型添加静态方法也很简单。继续我们的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方法。架构中的staticsmethods对象是什么?有什么区别,为什么我会使用一个而不是另一个?

8 个答案:

答案 0 :(得分:55)

statics是模型上定义的方法。 methods在文档(实例)上定义。

你可以做

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

然后您可以使用文档实例fido来执行

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

答案 1 :(得分:1)

对我来说,这并不意味着在'static'甚至前面的'instance'关键字前添加 Mongoose 即可添加任何内容。

我相信static的含义和目的在任何地方都是相同的,即使对于外来语言或某种表示模型的驱动程序也是如此,后者代表用于构建块的Model,就像另一个面向对象的编程一样。例如,也是如此。

来自维基百科: 面向对象编程(OOP)中的方法是与消息和对象相关联的过程。对象由数据和行为组成。数据和行为包括一个接口,该接口指定该对象的各种使用者[1]中的任何一个可以如何使用该对象。

数据表示为对象的属性,行为表示为对象的方法。例如,Window对象可以具有诸如open和close之类的方法,而其状态(无论在任何给定时间点处于打开还是关闭状态)都是一个属性。

静态方法旨在与类的所有实例相关,而不与任何特定实例相关。从某种意义上说,它们类似于静态变量。一个示例是将类的每个实例的所有变量的值求和的静态方法。例如,如果有一个Product类,则可能有一个静态方法来计算所有产品的平均价格。

Math.max(double a,double b)

此静态方法没有所属对象,并且无法在实例上运行。它从其自变量中接收所有信息。[7]

即使该类的实例尚不存在,也可以调用静态方法。静态方法之所以称为“静态”,是因为它们是在编译时根据调用的类来解析的,而不是像实例方法那样动态地解析的,实例方法是根据对象的运行时类型进行多态解析的。

https://en.wikipedia.org/wiki/Method_(computer_programming)

答案 2 :(得分:0)

数据库逻辑应封装在数据模型内。猫鼬提供了两种方法,方法和静态方法。方法为文档添加了一个实例方法,而静态方法为Models本身添加了静态“类”方法。static关键字定义了模型的静态方法。不会在模型实例上调用静态方法。而是在模型本身上调用它们。这些通常是实用程序功能,例如用于创建或克隆对象的功能。如下例所示:

Array#filter

有关更多信息:https://osmangoni.info/posts/separating-methods-schema-statics-mongoose/

答案 3 :(得分:0)

  • std::map::find()用于std::map<chainin, chainout> chainmap; string FADEDevicePinInfo::getNetAtPinIdTmTidMss (const LONG p, const string tm, const string tid, const LONG mss) { chainin ci; ci.tm = tm; //ci.tdi = tid; ci.tdi = ""; ci.mss = (short) mss; ci.pinid = p; std::map<chainin, chainout>::iterator it = chainmap.find(ci); if (it != chainmap.end()) { cout << "BDEBUG: found" << " p[" << it->first.pinid << "]" << " tm[" << it->first.tm << "]" << " mss[" << it->first.mss << "]" << " : " << it->second.cs << endl; } } 方法。
  • .statics用于static方法。
.methods

答案 4 :(得分:0)

staticsmethods 几乎相同,但允许定义直接存在于模型中的函数。

statics 属于 Modelmethods 属于 Instance

答案 5 :(得分:0)

Static methods 适用于定义它们的整个模型,而 instance methods 仅适用于集合中的特定文档。

this 在静态方法的上下文中返回整个模型,而 this 在实例方法的上下文中返回文档。

比如说:

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()

答案 6 :(得分:0)

正如大家所说,当我们想对单个文档进行操作时使用方法,而当我们想对整个集合进行操作时我们使用静态方法。但为什么呢?

比方说,我们有一个架构:

var AnimalSchema = new Schema({
  name: String,
  type: String
});

现在如文档中所述,如果您需要检查数据库中特定文档的相似类型 你可以这样做:

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,我们必须拥有它。 很简单,每当我们需要特定 obj/document 的帮助来做某事时,我们都会使用方法。

现在偶然我们还需要整个模型来搜索更苗条的类型, 尽管它不能直接在方法中使用(记住 this.modelName 将返回 undefined)。我们可以通过将 this.model() 设置为我们首选的模型来获得它,在本例中为 Animal。 这就是方法的全部。

现在,statics 可以使用整个模型。 1)假设您想计算您将使用静态的所有动物的总价格(假设模型具有价格字段)[因为您不需要任何特定的动物对象,所以我们不会使用方法] 2)你想找到黄色皮肤的动物(假设模型有皮肤场),你将使用静力学。 [因为我们不需要任何特定的动物对象,所以我们不会使用方法]

例如:

 AnimalSchema.statics.findYellowSkin = function findSimilarType (cb) {
        return **this**.find({ skin: "yellow" }, cb);
    };

记住,在方法中 this 指的是模型,所以 this.modelName 将返回 Animal(在我们的例子中)。

但就像方法一样,在这里我们也可以(但我们不需要)使用设置模型。

AnimalSchema.methods.findSimilarType = function findSimilarType (cb) {
    return **this.model('Animal')**.find({ skin: "yellow" }, cb);   //just like in methods
};

所以你可以看到静态和方法非常相似。

<块引用>

每当你有一个文件并且你需要处理它时, 使用方法。每当你需要对整体做某事时 模型/集合,使用静态。

答案 7 :(得分:-1)

还请查阅mongoosejs中有关文档和模型的文档

[https://mongoosejs.com/docs/documents.html][1]

它帮助我更好地了解“静态”方法与“实例”方法