【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