mongodb Mongoose“静态”方法与“示例”方法

sshcrbum  于 2022-12-29  发布在  Go
关注(0)|答案(7)|浏览(237)

我相信这个问题类似于this one,但术语不同。来自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);
}

现在我们所有的动物示例都有一个findSimilarTypes方法可用。
然后:
向Model添加静态方法也很简单。继续我们的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方法。Schema中的staticsmethods对象是什么?它们有什么区别?为什么要使用其中一个而不是另一个?

h9a6wy2h

h9a6wy2h1#

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是一个模型,它没有“类型”。findSimilarTypes需要一个this.type,而该this.type在Animals模型中不存在,只有文档示例才会包含该属性,如模型中定义的那样。
同样,您也不会执行fido.findByName,因为findByName需要搜索所有文档,而fido只是一个***文档。
¹从技术上讲,你可以,因为instance可以访问集合(this.constructorthis.model('Animal')),但是拥有一个不使用示例中任何属性的示例方法是没有意义的(至少在本例中是这样)。

brqmpdu1

brqmpdu12#

数据库逻辑应该封装在数据模型中。Mongoose提供了两种方法,方法和静态。方法为文档添加示例方法,而静态为模型本身添加静态“类”方法。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/

rvpgvaaj

rvpgvaaj3#

对我来说,这并不意味着通过在“static”或“instance”关键字前面添加Mongoose来添加任何东西。
我认为static的意义和目的在任何地方都是一样的,即使对于一种外来语言或者某种驱动程序来说也是如此,它代表了构建块的模型,就像另一个面向对象的编程一样。

维基百科:****在面向对象编程(OOP)中,方法是一个与消息和对象相关联的过程。对象由数据和行为组成。数据和行为组成一个接口,它指定了对象的任何消费者如何使用对象。

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

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

数学最大值(双a,双b)
这个静态方法没有所属对象,也不在示例上运行。它从参数接收所有信息。[7]
静态方法可以被调用,即使类的示例还不存在。静态方法被称为“静态”,因为它们是在编译时基于调用它们的类来解析的,而不是像示例方法那样动态地解析的,示例方法是基于对象的运行时类型来多态解析的。
https://en.wikipedia.org/wiki/Method_(computer_programming)

62lalag4

62lalag44#

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

比如说,我们有一个模式:

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默认情况下与模型无关,它只用于特定的文档对象,但是我们可以使它与模型一起工作,使用这个. model('anyModelName ')。
那么为什么我们要用这种方法来寻找相似类型的动物呢?
为了找到相似类型的动物,我们 * 必须 * 有一个动物对象,我们可以找到相似类型的动物对象。

const Lion = await new Animal({name: Lion, type: "dangerous"});

接下来,当我们找到相似的类型时,我们首先需要Lion obj,我们必须拥有它。所以简单地说,每当我们需要某个特定的obj/document来做某件事时,我们就使用方法。
现在这里,偶然我们也需要whole model来搜索更粘的类型,尽管它不能直接在方法中使用(记住this. modelName将返回undefined)。我们可以通过将this. model()设置为我们的首选模型来获得它,在本例中是Animal。
现在,statics拥有了整个模型。1)假设您要计算总价格(假设模型有一个价格字段)在所有动物中,你将使用静态(因为你不需要任何特定的动物对象,所以我们不使用方法)2)你想找到黄色皮肤的动物(假设模型有一个皮肤场),你将使用静态。[为此,我们不需要任何特定的Animal对象,所以我们将不使用方法]
例如:

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

所以你可以看到,静力学和方法都非常相似。
无论何时你有一个文档并且你需要做些什么,使用方法;无论何时你需要对整个模型/集合做些什么,使用静态。

cgvd09ve

cgvd09ve5#

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

qij5mzcb6#

  • 使用.statics作为static方法。
  • .methods用于instance方法。
//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);
};
jfgube3f

jfgube3f7#

staticsmethods非常相似,但允许定义直接存在于您的Model上的函数。
statics属于型号,而methods属于示例

相关问题