Mongoose 是 Node.js 中最受欢迎的 ORM 框架之一,它能够让开发者轻松地连接 MongoDB 数据库并定义数据库模型。Mongoose 的一个强大特性就是可以使用模式继承(Schema Inheritance),这让我们可以更加方便地定义和组织我们的数据模型。本文将详细介绍如何使用 Mongoose 进行模式继承。
定义好基础模型
首先,我们需要定义好基础模型,这个基础模型包含了我们需要的字段和方法。例如,我们定义了一个名为 Person 的模型,包含了 name 和 age 两个字段和 getInfo() 方法:
// www.javascriptcn.com code example
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const personSchema = new Schema({
name: String,
age: Number
});
personSchema.methods.getInfo = function() {
console.log('My name is ' + this.name + ', I am ' + this.age + ' years old.');
};
const Person = mongoose.model('Person', personSchema);
module.exports = Person;使用 $ref 进行模式继承
在 Mongoose 中,我们可以使用 $ref 字段来指向一个已存在的模型,这个已存在的模型就可以被继承。例如,我们希望定义一个名为 Employee 的模型,它继承了 Person 模型,我们可以这样定义:
// www.javascriptcn.com code example
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Person = require('./person');
const employeeSchema = new Schema({
salary: Number,
position: String,
person: {
type: Schema.Types.ObjectId,
ref: 'Person'
}
});
const Employee = mongoose.model('Employee', employeeSchema);
module.exports = Employee;上面的代码中,我们定义了一个 person 字段,它的值是指向 Person 模型的一个对象 ID,这就实现了我们对 Person 模型的继承。
现在,在 Employee 模型中我们就可以直接使用 name 和 age 字段了。例如,我们可以这样定义一个 Employee 实例:
// www.javascriptcn.com code example
const Person = require('./models/person');
const Employee = require('./models/employee');
const person = new Person({
name: 'Alex',
age: 30
});
const employee = new Employee({
person: person,
salary: 10000,
position: 'Manager'
});
employee.person.getInfo();执行上面的代码,输出的结果将是:
My name is Alex, I am 30 years old.
由于 Employee 模型继承了 Person 模型的 name 和 age 字段,我们就可以直接使用 person 对象的 getInfo() 方法。
使用 discriminators 进行模式继承
除了使用 $ref 进行模式继承外,Mongoose 还提供了更加强大的模式继承方式:discriminators。
Discriminators 可以让我们定义一个基本模型,并且定义多个其它模型,并指定它们继承自基本模型并覆盖一些属性。这个方式适用于定义大量有相同属性但是在某些属性上有不同的模型。
例如,我们希望定义一个 Person 模型,基于它又有三个子模型:Employee、Customer 和 Vendor。我们可以这样定义基础模型:
// www.javascriptcn.com code example
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const personSchema = new Schema({
name: String,
age: Number,
address: String,
phone: String
}, { discriminatorKey: 'kind' });上面的代码中,我们除了定义了 name、age、address 和 phone 四个字段之外,还定义了一个名为 kind 的字段,用于判断子模型的类型。
接下来,我们继续定义 Employee,并指定它继承自 Person:
const employeeSchema = new Schema({
salary: Number,
position: String
});
const Employee = mongoose.model('Employee', employeeSchema);
module.exports = Employee.discriminator('Employee', personSchema);上面的代码中,我们使用了 Employee.discriminator 方法,它的第一个参数是子模型的名称,第二个参数是基础模型的定义。
现在,我们就可以使用 Employee 模型了。例如,我们可以这样定义一个 Employee 实例:
// www.javascriptcn.com code example
const Employee = require('./models/employee');
const employee = new Employee({
name: 'Alex',
age: 30,
address: 'Beijing',
phone: '13888888888',
salary: 10000,
position: 'Manager'
});
console.log(employee);执行上面的代码,输出的结果将是:
// www.javascriptcn.com code example
{
kind: 'Employee',
name: 'Alex',
age: 30,
address: 'Beijing',
phone: '13888888888',
salary: 10000,
position: 'Manager',
_id: new ObjectId("...")
}我们可以看到,employee 对象中包含了 Person 模型和 Employee 模型的所有属性。
需要注意的是,discriminatorKey 要与子模型中的 kind 字段一致。否则在执行 Employee.discriminator 方法时会出错。另外,使用 discriminator 时,子模型不能定义 discriminatorKey 字段。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d647e7a941bf7134bfbbd5