【Mongoose】Mongoose概念
名称 | 概念 | 作用 | 官方解释 |
---|---|---|---|
Schema | 模式 | 定义文档的数据结构和属性类型 | 每个 schema 都会映射到一个 MongoDB collection ,并定义这个 collection 里的文档的构成 |
Model | 模型 | 一个 Model 等同于一个 collection | Models 是从 Schema 编译而来的构造函数,Models 的实例是 documents |
document | 文档 | 一个 document 就是 collection 中的一条数据 | mongoose 文档表示与存储在 MongoDB 中的文档的一对一映射。每个文档都是其 Model 的一个实例。 |
Schema
Schema
用来定义文档的结构,需要用 mongoose.model('Test', schema)
将 Schema
编译 为 Model
。
const schema = new Schema({
living: Boolean,
age: { type: Number, min: 18, max: 65, default: 10 },
array: [],
ofString: [String],
ofArrayOfNumbers: [[Number]],
mapOfString: {
type: Map,
of: String,
},
});
避免使用箭头函数声明方法。
SchemaType 选项
数组拥有隐含的默认值:[]
(空数组),可以设置 default: undefined
来将默认值设为 undefined
。
const schema = new Schema({
n: {
type: String, // 类型
required: true, // 是否必填
alias: "name", // 别名
timestamps: false, // 是否自动添加时间戳:createdAt and updatedAt
},
});
timestamps 时间戳
timestamps
属性设置为 true
后会自动在文档中添加两个 Date
类型的属性,createdAt
为创建时的时间戳,updatedAt
为最后一次更新的时间戳。
会修改 updatedAt
的方法:save()
、updateOne()
、updateMany()
、findOneAndUpdate()
、update()
、replaceOne()
、bulkWrite()
。
这些方法都可以通过设置 timestamps: false
不修改 updatedAt
。
实例方法
定义在 Schema
上的实例方法可以在 document
上调用。
const animalSchema = new Schema({ name: String, type: String });
animalSchema.methods.findSimilarTypes = function (cb) {
return mongoose.model("Animal").find({ type: this.type }, cb);
};
const Animal = mongoose.model("Animal", animalSchema);
const dog = new Animal({ type: "dog" });
dog.findSimilarTypes((err, dogs) => {
console.log(dogs); // woof
});
静态方法
定义在 Schema
上的静态方法可以在 Model
上调用。
const animalSchema = new Schema({ name: String, type: String });
// 第一种定义方式
animalSchema.statics.findByName = function (name) {
return this.find({ name: new RegExp(name, "i") });
};
// 第二种定义方式
animalSchema.static("findByBreed", function (breed) {
return this.find({ breed });
});
const Animal = mongoose.model("Animal", animalSchema);
Animal.findByName();
查询助手
用于扩展 mongoose
的链式查询。
const animalSchema = new Schema({ name: String, type: String });
animalSchema.query.byName = function (name) {
return this.where({ name: new RegExp(name, "i") });
};
const Animal = mongoose.model("Animal", animalSchema);
Animal.find()
.byName("fido")
.exec((err, animals) => {
console.log(animals);
});
虚拟数据
Virtuals
是可以获取和设置但不会持久保存到 MongoDB
的文档属性。
const personSchema = new Schema({
name: {
first: String,
last: String,
},
});
personSchema
.virtual("fullName")
.get(function () {
return this.name.first + " " + this.name.last;
})
.set(function (v) {
this.name.first = v.substr(0, v.indexOf(" "));
this.name.last = v.substr(v.indexOf(" ") + 1);
});
axl.fullName = "William Rose"; // Now `axl.name.first` is "William"
别名
为属性设置别名,在开发时保证可读性,同时减少数据库中存储数据的 size
。
const personSchema = new Schema({
n: {
type: String,
// 现在,访问'name'将获得'n'的值,设置'name'将设置'n'的值`
alias: "name",
},
});
选项
collection
mongoose
默认将 Model
名称作为 collection
名称,这种默认行为会将名称修改为复数且小写。
通过 Schema
的 collection
选项可以指定 collection
,设置后 mongoose.model()
一参的名称无效。
const kittySchema = new mongoose.Schema(
{
name: String,
},
{
collection: "kitty",
}
);
Model
一个 Model
等同于一个 collection
。调用 mongoose.model()
生成一个模型的同时 mongoose
会同步在数据库中创建一个 collection
。
需注意 mongoose.model("Kitten", kittySchema)
方法不传第三个参数时 mongoose
会将 collection
名称设定为一参的复数形式,并且生成的 collection
名称都是小写。
.model()
函数会复制 schema
。在调用 .model()
之前确保你已经添加了所有你想要的东西到 schema
,包括钩子。
const Kitten = mongoose.model("Kitten", kittySchema);
// collection:kittens
const Kitten = mongoose.model("Ny", kittySchema);
// collection:nies
const Kitten = mongoose.model("Kitten", kittySchema, "Kitten");
// collection:kitten