模式类型(SchemaTypes)
SchemaType 处理字段路径各种属性的定义( defaults, validation, getters, setters, field selection defaults for queries, and other general characteristics for Strings and Numbers)
以下是 mongoose 的所有合法 SchemaTypes:
- String
- Number
- Date
- Buffer
- Boolean
- Mixed
- ObjectId
- Array
- Decimal128
Example
var schema = new Schema({
name: String,
binary: Buffer,
living: Boolean,
updated: { type: Date, default: Date.now },
age: { type: Number, min: 18, max: 65 },
mixed: Schema.Types.Mixed,
_someId: Schema.Types.ObjectId,
decimal: Schema.Types.Decimal128,
array: [],
ofString: [String],
ofNumber: [Number],
ofDates: [Date],
ofBuffer: [Buffer],
ofBoolean: [Boolean],
ofMixed: [Schema.Types.Mixed],
ofObjectId: [Schema.Types.ObjectId],
ofArrays: [[]],
ofArrayOfNumbers: [[Number]],
nested: {
stuff: { type: String, lowercase: true, trim: true }
}
})
// example use
var Thing = mongoose.model('Thing', schema);
var m = new Thing;
m.name = 'Statue of Liberty';
m.age = 125;
m.updated = new Date;
m.binary = new Buffer(0);
m.living = false;
m.mixed = { any: { thing: 'i want' } };
m.markModified('mixed');
m._someId = new mongoose.Types.ObjectId;
m.array.push(1);
m.ofString.push("strings!");
m.ofNumber.unshift(1,2,3,4);
m.ofDates.addToSet(new Date);
m.ofBuffer.pop();
m.ofMixed = [1, [], 'three', { four: 5 }];
m.nested.stuff = 'good';
m.save(callback);
SchemaType 选项
你可以直接声明 schema type 为某一种 type,或者赋值一个含有 type
属性的对象。
var schema1 = new Schema({
test: String // `test` is a path of type String
});
var schema2 = new Schema({
test: { type: String } // `test` is a path of type string
});
除了 type 属性,你还可以对这个字段路径指定其他属性。 如果你要在保存之前要把字母都改成小写:
var schema2 = new Schema({
test: {
type: String,
lowercase: true // Always convert `test` to lowercase
}
});
lowercase
属性只作用于字符串。以下有一些全部 type 可用的选项和一些限定部分 type 使用的选项。
全部可用
required
: 布尔值或函数 如果值为真,为此属性添加 required 验证器default
: 任何值或函数 设置此路径默认值。如果是函数,函数返回值为默认值select
: 布尔值 指定 query 的默认 projectionsvalidate
: 函数 adds a validator function for this propertyget
: 函数 使用Object.defineProperty()
定义自定义 getterset
: 函数 使用Object.defineProperty()
定义自定义 setteralias
: 字符串 仅mongoose >= 4.10.0。 为该字段路径定义虚拟值 gets/sets
var numberSchema = new Schema({
integerOnly: {
type: Number,
get: v => Math.round(v),
set: v => Math.round(v),
alias: 'i'
}
});
var Number = mongoose.model('Number', numberSchema);
var doc = new Number();
doc.integerOnly = 2.001;
doc.integerOnly; // 2
doc.i; // 2
doc.i = 3.001;
doc.integerOnly; // 3
doc.i; // 3
索引相关
你可以使用 schema type 选项定义MongoDB indexes。
index
: 布尔值 是否对这个属性创建索引unique
: 布尔值 是否对这个属性创建唯一索引sparse
: 布尔值 是否对这个属性创建稀疏索引
var schema2 = new Schema({
test: {
type: String,
index: true,
unique: true // Unique index. If you specify `unique: true`
// specifying `index: true` is optional if you do `unique: true`
}
});
String
lowercase
: 布尔值 是否在保存前对此值调用.toLowerCase()
uppercase
: 布尔值 是否在保存前对此值调用.toUpperCase()
trim
: 布尔值 是否在保存前对此值调用.trim()
match
: 正则表达式 创建验证器检查这个值是否匹配给定正则表达式enum
: 数组 创建验证器检查这个值是否包含于给定数组
Number
min
: 数值 创建验证器检查属性是否大于或等于该值max
: 数值 创建验证器检查属性是否小于或等于该值
Date
min
: Datemax
: Date
使用注意
Dates
内建 Date
方法 不会触发 mongoose 修改跟踪逻辑, 如果你对使用 setMonth()
修改文档里的 Date
, mongoose在 doc.save()
的时候是察觉不到这个文档发生了变化的,因此保存不到数据库。 如果你一定要用内建 Date
方法, 请手动调用 doc.markModified('pathToYourDate')
告诉 mongoose 你修改了数据。
var Assignment = mongoose.model('Assignment', { dueDate: Date });
Assignment.findOne(function (err, doc) {
doc.dueDate.setMonth(3);
doc.save(callback); // THIS DOES NOT SAVE YOUR CHANGE
doc.markModified('dueDate');
doc.save(callback); // works
})
Mixed
一个啥都可以放的 SchemaType , 虽然便利,但也会让数据难以维护。 Mixed 可以通过 Schema.Types.Mixed 或 传入一个空对象定义。以下三种方法效果一致:
var Any = new Schema({ any: {} });
var Any = new Schema({ any: Object });
var Any = new Schema({ any: Schema.Types.Mixed });
因为这是个 schema-less type, 所以你可以赋值为任意类型, 但是 mongoose 无法自动检测并保存你的修改。 要告诉 Mongoose 你修改了 Mixed type 的值,调用 文档的 .markModified(path)
方法, 传入你的 Mixed 字段路径。
person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved
ObjectIds
要指定类型为 ObjectId,在声明中使用 Schema.Types.ObjectId
。
var mongoose = require('mongoose');
var ObjectId = mongoose.Schema.Types.ObjectId;
var Car = new Schema({ driver: ObjectId });
// or just Schema.ObjectId for backwards compatibility with v2
Arrays
创造 SchemaTypes 或子文档数组。
var ToySchema = new Schema({ name: String });
var ToyBox = new Schema({
toys: [ToySchema],
buffers: [Buffer],
string: [String],
numbers: [Number]
// ... etc
});
注意:指定空数组相当于 Mixed
。以下操作相当于创建 Mixed
数组:
var Empty1 = new Schema({ any: [] });
var Empty2 = new Schema({ any: Array });
var Empty3 = new Schema({ any: [Schema.Types.Mixed] });
var Empty4 = new Schema({ any: [{}] });
数组的默认值是 []
(空数组)。
var Toy = mongoose.model('Test', ToySchema);
console.log((new Toy()).toys); // []
要手动把默认值设置为 undefined
,从而覆盖 []
。
var ToySchema = new Schema({
toys: {
type: [ToySchema],
default: undefined
}
});
创建自定义 Type
Mongoose 可以扩展自定义 SchemaTypes。搜索 插件 页面,查找类似mongoose-long, mongoose-int32, 以及其他 types 的兼容 types。
schema.path()
函数
schema.path()
函数为给定字段路径返回实例化 schema type。
var sampleSchema = new Schema({ name: { type: String, required: true } });
console.log(sampleSchema.path('name'));
// Output looks like:
/**
* SchemaString {
* enumValues: [],
* regExp: null,
* path: 'name',
* instance: 'String',
* validators: ...
*/
这个函数可以检查给定字段路径的检验器和类型等信息。
下一步
这章我们介绍了 SchemaTypes
,下一个章节将会介绍 Connections。