SchemaTypes
SchemaTypes handle definition of path defaults, validation, getters, setters, field selection defaults for queries, and other general characteristics for Mongoose document properties.SchemaTypes处理路径默认值、验证、getters、setters、查询的字段选择默认值的定义,以及Mongoose文档属性的其他一般特征。
What is a SchemaType?什么是架构类型?Thetype
Keytype
键SchemaType Options架构类型选项Usage Notes使用说明- Getters
Custom Types自定义类型Theschema.path()
Functionschema.path()
函数Further Reading进一步阅读
What is a SchemaType?什么是架构类型?
You can think of a Mongoose schema as the configuration object for a Mongoose model. 您可以将Mongoose架构视为Mongoose模型的配置对象。A SchemaType is then a configuration object for an individual property. SchemaType就是一个单独属性的配置对象。A SchemaType says what type a given path should have, whether it has any getters/setters, and what values are valid for that path.SchemaType说明给定路径应该具有什么类型,是否具有任何getter/setter,以及哪些值对该路径有效。
const schema = new Schema({ name: String });
schema.path('name') instanceof mongoose.SchemaType; // true
schema.path('name') instanceof mongoose.Schema.Types.String; // true
schema.path('name').instance; // 'String'
A SchemaType is different from a type. In other words, SchemaType与类型不同。换句话说,mongoose.ObjectId !== mongoose.Types.ObjectId
. mongoose.ObjectId !== mongoose.Types.ObjectId
。A SchemaType is just a configuration object for Mongoose. SchemaType只是Mongoose的一个配置对象。An instance of the mongoose.ObjectId
SchemaType doesn't actually create MongoDB ObjectIds, it is just a configuration for a path in a schema.mongoose.ObjectId
架构类型的实例实际上并没有创建MongoDB ObjectId,它只是架构中路径的配置。
The following are all the valid SchemaTypes in Mongoose. Mongoose plugins can also add custom SchemaTypes like int32. 以下是Mongoose中所有有效的SchemaTypes。Mongoose插件还可以添加像int32这样的自定义SchemaTypes。Check out Mongoose's plugins search to find plugins.查看Mongoose的插件搜索以查找插件。
Example示例
const 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 }
},
map: Map,
mapOfString: {
type: Map,
of: String
}
});
// example use
const Thing = mongoose.model('Thing', schema);
const m = new Thing;
m.name = 'Statue of Liberty';
m.age = 125;
m.updated = new Date;
m.binary = Buffer.alloc(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.map = new Map([['key', 'value']]);
m.save(callback);
The type
Keytype
键
type
Keytype
is a special property in Mongoose schemas. 是Mongoose架构中的一个特殊属性。When Mongoose finds a nested property named 当Mongoose在您的架构中找到一个名为type
in your schema, Mongoose assumes that it needs to define a SchemaType with the given type.type
的嵌套属性时,Mongoose假设它需要定义一个具有给定类型的SchemaType。
// 3 string SchemaTypes: 'name', 'nested.firstName', 'nested.lastName'
const schema = new Schema({
name: { type: String },
nested: {
firstName: { type: String },
lastName: { type: String }
}
});
As a consequence, you need a little extra work to define a property named 因此,您需要做一些额外的工作来在架构中定义一个名为type
in your schema. type
的属性。For example, suppose you're building a stock portfolio app, and you want to store the asset's 例如,假设你正在构建一个股票投资组合应用程序,并且你想存储资产的type
(stock, bond, ETF, etc.). type
(股票、债券、ETF等)。Naively, you might define your schema as shown below:天真地,您可以定义您的架构,如下所示:
const holdingSchema = new Schema({
// You might expect `asset` to be an object that has 2 properties,您可能期望`asset`是一个具有2个属性的对象,
// but unfortunately `type` is special in Mongoose so mongoose interprets this schema to mean that `asset` is a string但不幸的是,`type`在Mongoose中是特殊的,所以Mongoose将这个模式解释为`asset`是一个字符串
asset: {
type: String,
ticker: String
}
});
However, when Mongoose sees 然而,当Mongoose看到type: String
, it assumes that you mean asset
should be a string, not an object with a property type
. type:String
时,它假设您的意思是asset
应该是字符串,而不是具有属性type
的对象。The correct way to define an object with a property 定义具有属性type
is shown below.type
的对象的正确方法如下所示。
const holdingSchema = new Schema({
asset: {
// Workaround to make sure Mongoose knows `asset` is an object and `asset.type` is a string, rather than thinking `asset` is a string.设法确保Mongoose知道`asset`是一个对象,`asset.type`是一个字符串,而不是认为`asset`是字符串。
type: { type: String },
ticker: String
}
});
SchemaType Options架构类型选项
You can declare a schema type using the type directly, or an object with a 您可以直接使用类型声明架构类型,也可以使用type
property.type
属性声明对象。
const schema1 = new Schema({
test: String // `test` is a path of type String是字符串类型的路径
});
const schema2 = new Schema({
// The `test` object contains the "SchemaType options"`test`对象包含“SchemaType选项”
test: { type: String } // `test` is a path of type string是字符串类型的路径
});
In addition to the type property, you can specify additional properties for a path. 除了类型属性外,还可以为路径指定其他属性。For example, if you want to lowercase a string before saving:例如,如果要在保存之前将字符串小写:
const schema2 = new Schema({
test: {
type: String,
lowercase: true // Always convert `test` to lowercase
}
});
You can add any property you want to your SchemaType options. 您可以将任何需要的属性添加到SchemaType选项中。Many plugins rely on custom SchemaType options. 许多插件依赖于自定义SchemaType选项。For example, the mongoose-autopopulate plugin automatically populates paths if you set 例如,如果您在SchemaType选项中设置autopopulate: true
in your SchemaType options. autopopulate:true
,mongoose-autopopulate插件会自动填充路径。Mongoose comes with support for several built-in SchemaType options, like Mongoose支持几个内置的SchemaType选项,比如上面例子中的lowercase
in the above example.lowercase
。
The lowercase
option only works for strings. lowercase
选项仅适用于字符串。There are certain options which apply for all schema types, and some that apply for specific schema types.有些选项适用于所有模式类型,有些则适用于特定的模式类型。
All Schema Types所有架构类型
required
: boolean or function, if true adds a required validator for this property:boolean或function,如果为true
,则为该属性添加 必需的验证器default
: Any or function, sets a default value for the path.:任意或函数,设置路径的默认值。If the value is a function, the return value of the function is used as the default.如果该值是一个函数,则函数的返回值将用作默认值。select
: boolean, specifies default projections for queries:boolean,指定查询的默认投影validate
: function, adds a validator function for this property:函数,为此属性添加一个验证器函数get
: function, defines a custom getter for this property using Object.defineProperty().:函数,使用Object.defineProperty()为此属性定义一个自定义getter。set
: function, defines a custom setter for this property using Object.defineProperty().:函数,使用Object.defineProperty()为此属性定义一个自定义setter。alias
: string, mongoose >= 4.10.0 only. Defines a virtual with the given name that gets/sets this path.:字符串,仅限mongoose>=4.10.0。定义具有给定名称的虚拟机,以获取/设置此路径。immutable
: boolean, defines path as immutable.:boolean,将路径定义为不可变。Mongoose prevents you from changing immutable paths unless the parent document hasMongoose防止您更改不可变的路径,除非父文档具有isNew: true
.isNew:true
。transform
: function, Mongoose calls this function when you call Document#toJSON() function, including when you JSON.stringify() a document.:函数,Mongoose在调用Document#toJSON()函数时调用此函数,包括当您将JSONstringify()
作为文档时。
const numberSchema = new Schema({
integerOnly: {
type: Number,
get: v => Math.round(v),
set: v => Math.round(v),
alias: 'i'
}
});
const Number = mongoose.model('Number', numberSchema);
const doc = new Number();
doc.integerOnly = 2.001;
doc.integerOnly; // 2
doc.i; // 2
doc.i = 3.001;
doc.integerOnly; // 3
doc.i; // 3
Indexes索引
You can also define MongoDB indexes using schema type options.您还可以使用模式类型选项定义MongoDB索引。
index
: boolean, whether to define an index on this property.:boolean,是否在此属性上定义索引。unique
: boolean, whether to define a unique index on this property.:boolean,是否在此属性上定义唯一索引。sparse
: boolean, whether to define a sparse index on this property.:boolean,是否在此属性上定义稀疏索引。
const schema2 = new Schema({
test: {
type: String,
index: true,
unique: true // Unique index. If you specify `unique: true`唯一索引。如果指定`unique: true`
// specifying `index: true` is optional if you do `unique: true`如果指定了`unique: true`,则指定`index: true`是可选的
}
});
String
lowercase
: boolean, whether to always call:boolean,是否总是对值调用.toLowerCase()
on the value.toLowerCase()
uppercase
: boolean, whether to always call:boolean,是否总是对值调用.toUpperCase()
on the value.toUpperCase()
trim
: boolean, whether to always call .trim() on the value:boolean,是否总是对值调用.trim()match
: RegExp, creates a validator that checks if the value matches the given regular expression:RegExp,创建一个验证器,用于检查值是否与给定的正则表达式匹配enum
: Array, creates a validator that checks if the value is in the given array.:数组,创建一个验证器来检查该值是否在给定的数组中。minLength
: Number, creates a validator that checks if the value length is not less than the given number:Number,创建一个验证器,用于检查值长度是否不小于给定的数字maxLength
: Number, creates a validator that checks if the value length is not greater than the given number:Number,创建一个验证器,用于检查值长度是否不大于给定的数字populate
: Object, sets default populate options:对象,设置默认填充选项
Number
min
: Number, creates a validator that checks if the value is greater than or equal to the given minimum.:Number,创建一个验证器,用于检查该值是否大于或等于给定的最小值。max
: Number, creates a validator that checks if the value is less than or equal to the given maximum.:Number,创建一个验证器,用于检查该值是否小于或等于给定的最大值。enum
: Array, creates a validator that checks if the value is strictly equal to one of the values in the given array.:数组,创建一个验证器,用于检查该值是否严格等于给定数组中的一个值。populate
: Object, sets default populate options:对象,设置默认填充选项
Date
min
: Date, creates a validator that checks if the value is greater than or equal to the given minimum.:Date,创建一个验证器,用于检查该值是否大于或等于给定的最小值。max
: Date, creates a validator that checks if the value is less than or equal to the given maximum.:Date,创建一个验证器,用于检查该值是否小于或等于给定的最大值。expires
: Number or String, creates a TTL index with the value expressed in seconds.:Number或String,创建一个TTL索引,其值以秒为单位。
ObjectId
populate
: Object, sets default populate options:对象,设置默认填充选项
Usage Notes使用说明
String
To declare a path as a string, you may use either the 要将路径声明为字符串,可以使用全局构造函数String
global constructor or the string 'String'
.String
或字符串'String'
。
const schema1 = new Schema({ name: String }); // name will be cast to string
const schema2 = new Schema({ name: 'String' }); // Equivalent
const Person = mongoose.model('Person', schema2);
If you pass an element that has a 如果您传递一个具有toString()
function, Mongoose will call it, unless the element is an array or the toString()
function is strictly equal to Object.prototype.toString()
.toString()
函数的元素,Mongoose将调用它,除非该元素是一个数组,或者toString()
函数严格等于Object.prototype.toString()
。
new Person({ name: 42 }).name; // "42" as a string
new Person({ name: { toString: () => 42 } }).name; // "42" as a string
// "undefined", will get a cast error if you `save()` this document,如果`save()`此文档,将得到一个强制转换错误
new Person({ name: { foo: 42 } }).name;
Number
To declare a path as a number, you may use either the 要将路径声明为数字,可以使用全局构造函数Number
global constructor or the string 'Number'
.Number
或字符串'Number'
。
const schema1 = new Schema({ age: Number }); // age will be cast to a Number
const schema2 = new Schema({ age: 'Number' }); // Equivalent
const Car = mongoose.model('Car', schema2);
There are several types of values that will be successfully cast to a Number.有几种类型的值将成功转换为数字。
new Car({ age: '15' }).age; // 15 as a Number
new Car({ age: true }).age; // 1 as a Number
new Car({ age: false }).age; // 0 as a Number
new Car({ age: { valueOf: () => 83 } }).age; // 83 as a Number
If you pass an object with a 如果您传递一个带有valueOf()
function that returns a Number, Mongoose will call it and assign the returned value to the path.valueOf()
函数的对象,该函数返回一个Number,Mongoose将调用它并将返回的值分配给路径。
The values null
and undefined
are not cast.null
值和undefined
值不进行强制转换。
NaN, strings that cast to NaN, arrays, and objects that don't have a NaN、转换为NaN的字符串、数组和没有valueOf()
function will all result in a CastError once validated, meaning that it will not throw on initialization, only when validated.valueOf()
函数的对象在经过验证后都将导致CastError,这意味着它不会在初始化时抛出,只有在经过验证时才会抛出。
Dates
Built-in 内置的Date
methods are not hooked into the mongoose change tracking logic which in English means that if you use a Date
in your document and modify it with a method like setMonth()
, mongoose will be unaware of this change and doc.save()
will not persist this modification. Date
方法没有连接到mongoose更改跟踪逻辑中,这在英语中意味着,如果您在文档中使用Date
并使用setMonth()
等方法进行修改,mongoose将不知道此更改,并且doc.save()
将不会保留此修改。If you must modify 如果必须使用内置方法修改Date
types using built-in methods, tell mongoose about the change with doc.markModified('pathToYourDate')
before saving.Date
类型,请在保存之前使用doc.markModified('pathToYourDate')
将更改告知mongoose。
const 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生效了
});
Buffer
To declare a path as a Buffer, you may use either the 要将路径声明为Buffer,可以使用全局构造函数Buffer
global constructor or the string 'Buffer'
.Buffer
或字符串'Buffer'
。
const schema1 = new Schema({ binData: Buffer }); // binData will be cast to a Buffer将被强制转换为Buffer
const schema2 = new Schema({ binData: 'Buffer' }); // Equivalent
const Data = mongoose.model('Data', schema2);
Mongoose will successfully cast the below values to buffers.Mongoose将成功地将以下值强制转换为缓冲区。
const file1 = new Data({ binData: 'test'}); // {"type":"Buffer","data":[116,101,115,116]}
const file2 = new Data({ binData: 72987 }); // {"type":"Buffer","data":[27]}
const file4 = new Data({ binData: { type: 'Buffer', data: [1, 2, 3]}}); // {"type":"Buffer","data":[1,2,3]}
Mixed
An "anything goes" SchemaType. Mongoose will not do any casting on mixed paths. 一个“随随便便”的SchemaType。Mongoose不会在混合路径上进行任何投射。You can define a mixed path using 您可以使用Schema.Types.Mixed
or by passing an empty object literal. Schema.Types.Mixed
或通过传递空的对象文字来定义混合路径。The following are equivalent.以下内容是等效的。
const Any = new Schema({ any: {} });
const Any = new Schema({ any: Object });
const Any = new Schema({ any: Schema.Types.Mixed });
const Any = new Schema({ any: mongoose.Mixed });
Since Mixed is a schema-less type, you can change the value to anything else you like, but Mongoose loses the ability to auto detect and save those changes. 由于Mixed是一种无模式的类型,您可以将值更改为您喜欢的任何其他类型,但Mongoose失去了自动检测和保存这些更改的能力。To tell Mongoose that the value of a Mixed type has changed, you need to call 要告诉Mongoose Mixed类型的值已经更改,您需要调用doc.markModified(path)
, passing the path to the Mixed type you just changed.doc.markModified(path)
,将路径传递给刚刚更改的Mixed型。
To avoid these side-effects, a Subdocument path may be used instead.为了避免这些副作用,可以使用子文档路径。
person.anything = { x: [3, 4, { y: 'changed' }] };
person.markModified('anything');
person.save(); // Mongoose will save changes to `anything`.
ObjectIds
An ObjectId is a special type typically used for unique identifiers. Here's how you declare a schema with a path ObjectId是一种特殊类型,通常用于唯一标识符。以下是如何使用ObjectId的路径driver
that is an ObjectId:driver
声明架构:
const mongoose = require('mongoose');
const carSchema = new mongoose.Schema({ driver: mongoose.ObjectId });
ObjectId
is a class, and ObjectIds are objects. 是一个类,而ObjectId是对象。However, they are often represented as strings. When you convert an ObjectId to a string using 然而,它们通常被表示为字符串。使用toString()
, you get a 24-character hexadecimal string:toString()
将ObjectId转换为字符串时,会得到一个24个字符的十六进制字符串:
const Car = mongoose.model('Car', carSchema);
const car = new Car();
car.driver = new mongoose.Types.ObjectId();
typeof car.driver; // 'object'
car.driver instanceof mongoose.Types.ObjectId; // true
car.driver.toString(); // Something like "5e1a0651741b255ddda996c4"
Boolean
Booleans in Mongoose are plain JavaScript booleans. Mongoose中的布尔值是纯JavaScript布尔值。By default, Mongoose casts the below values to 默认情况下,Mongoose将以下值强制转换为true
:true
:
true
'true'
1
'1'
'yes'
Mongoose casts the below values to Mongoose将以下值强制转换为false
:false
:
false
'false'
0
'0'
'no'
Any other value causes a CastError. 任何其他值都会导致CastError。You can modify what values Mongoose converts to true or false using the 您可以使用convertToTrue
and convertToFalse
properties, which are JavaScript sets.convertToTrue
和convertToFalse
属性修改Mongoose将哪些值转换为true
或false
,这两个属性是JavaScript Set。
const M = mongoose.model('Test', new Schema({ b: Boolean }));
console.log(new M({ b: 'nay' }).b); // undefined
// Set { false, 'false', 0, '0', 'no' }
console.log(mongoose.Schema.Types.Boolean.convertToFalse);
mongoose.Schema.Types.Boolean.convertToFalse.add('nay');
console.log(new M({ b: 'nay' }).b); // false
Arrays
Mongoose supports arrays of SchemaTypes and arrays of subdocuments. Mongoose支持SchemaTypes数组和子文档数组。Arrays of SchemaTypes are also called primitive arrays, and arrays of subdocuments are also called document arrays.SchemaTypes的数组也称为基元数组,子文档的数组也称为文档数组。
const ToySchema = new Schema({ name: String });
const ToyBoxSchema = new Schema({
toys: [ToySchema],
buffers: [Buffer],
strings: [String],
numbers: [Number]
// ... etc
});
Arrays are special because they implicitly have a default value of 数组之所以特殊,是因为它们隐式地具有默认值[]
(empty array).[]
(空数组)。
const ToyBox = mongoose.model('ToyBox', ToyBoxSchema);
console.log((new ToyBox()).toys); // []
To overwrite this default, you need to set the default value to 要覆盖此默认值,您需要将默认值设置为undefined
undefined
const ToyBoxSchema = new Schema({
toys: {
type: [ToySchema],
default: undefined
}
});
Note: specifying an empty array is equivalent to 注意:指定一个空数组相当于Mixed
. Mixed
。The following all create arrays of 以下全部创建Mixed
:Mixed
的数组:
const Empty1 = new Schema({ any: [] });
const Empty2 = new Schema({ any: Array });
const Empty3 = new Schema({ any: [Schema.Types.Mixed] });
const Empty4 = new Schema({ any: [{}] });
Maps
A MongooseMap
is a subclass of JavaScript's Map
class. MongooseMap
是JavaScript的Map
类的一个子类。In these docs, we'll use the terms 'map' and 在这些文档中,我们将交替使用术语“映射”和MongooseMap
interchangeably. MongooseMap
。In Mongoose, maps are how you create a nested document with arbitrary keys.在Mongoose中,映射是使用任意键创建嵌套文档的方式。
Note: In Mongoose Maps, keys must be strings in order to store the document in MongoDB.:在Mongoose Maps中,键必须是字符串才能将文档存储在MongoDB中。
const userSchema = new Schema({
// `socialMediaHandles` is a map whose values are strings. 是一个值为字符串的映射。
// A map's keys are always strings. You specify the type of values using `of`.映射的键始终是字符串。可以使用`of`指定值的类型。
socialMediaHandles: {
type: Map,
of: String
}
});
const User = mongoose.model('User', userSchema);
// Map { 'github' => 'vkarpov15', 'twitter' => '@code_barbarian' }
console.log(new User({
socialMediaHandles: {
github: 'vkarpov15',
twitter: '@code_barbarian'
}
}).socialMediaHandles);
The above example doesn't explicitly declare 上面的例子没有明确声明github
or twitter
as paths, but, since socialMediaHandles
is a map, you can store arbitrary key/value pairs. github
或twitter
为路径,但由于socialMediaHandles
是一个映射,因此可以存储任意的键/值对。However, since 但是,由于socialMediaHandles
is a map, you must use .get()
to get the value of a key and .set()
to set the value of a key.socialMediaHandles
是一个映射,因此必须使用.get()
来获取键的值,并使用.set()
来设置键的值。
const user = new User({
socialMediaHandles: {}
});
// Good很好
user.socialMediaHandles.set('github', 'vkarpov15');
// Works too同样起作用了
user.set('socialMediaHandles.twitter', '@code_barbarian');
// Bad, the `myspace` property will **not** get saved不好,`myspace`**不会**被保存
user.socialMediaHandles.myspace = 'fail';
// 'vkarpov15'
console.log(user.socialMediaHandles.get('github'));
// '@code_barbarian'
console.log(user.get('socialMediaHandles.twitter'));
// undefined
user.socialMediaHandles.github;
// Will only save the 'github' and 'twitter' properties将只保存“github”和“twitter”属性
user.save();
Map types are stored as BSON objects in MongoDB. 映射类型作为BSON对象存储在MongoDB中。Keys in a BSON object are ordered, so this means the insertion order property of maps is maintained.BSON对象中的关键帧是按顺序排列的,因此这意味着贴图的插入顺序属性是保持不变的。
Mongoose supports a special Mongoose支持一种特殊的$*
syntax to populate all elements in a map. $*
语法来填充映射中的所有元素。For example, suppose your 例如,假设您的socialMediaHandles
map contains a ref
:socialMediaHandles
映射包含一个ref
:
const userSchema = new Schema({
socialMediaHandles: {
type: Map,
of: new Schema({
handle: String,
oauth: {
type: ObjectId,
ref: 'OAuth'
}
})
}
});
const User = mongoose.model('User', userSchema);
To populate every 要填充每个socialMediaHandles
entry's oauth
property, you should populate on socialMediaHandles.$*.oauth
:socialMediaHandles
条目的oauth
属性,您应该在socialMediaHandles.$*.oauth
上进行填充:
const user = await User.findOne().populate('socialMediaHandles.$*.oauth');
UUID
Mongoose also supports a UUID type that stores UUID instances as Node.js buffers. Mongoose还支持将UUID实例存储为Node.js缓冲区的UUID类型。We recommend using ObjectIds rather than UUIDs for unique document ids in Mongoose, but you may use UUIDs if you need to.我们建议在Mongoose中使用ObjectId而不是UUID作为唯一的文档ID,但如果需要,您可以使用UUID。
In Node.js, a UUID is represented as an instance of 在Node.js中,UUID被表示为bson.Binary
type with a getter that converts the binary to a string when you access it. bson.Binary
类型的实例,带有一个getter,当您访问二进制文件时,该getter会将其转换为字符串。Mongoose stores UUIDs as binary data with subtype 4 in MongoDB.Mongoose将UUID存储为MongoDB中的子类型为4的二进制数据。
const authorSchema = new Schema({
_id: Schema.Types.UUID, // Can also do `_id: 'UUID'`
name: String
});
const Author = mongoose.model('Author', authorSchema);
const bookSchema = new Schema({
authorId: { type: Schema.Types.UUID, ref: 'Author' }
});
const Book = mongoose.model('Book', bookSchema);
const author = new Author({ name: 'Martin Fowler' });
console.log(typeof author._id); // 'string'
console.log(author.toObject()._id instanceof mongoose.mongo.BSON.Binary); // true
const book = new Book({ authorId: '09190f70-3d30-11e5-8814-0f4df9a59c41' });
To create UUIDs, we recommend using Node's built-in UUIDv4 generator.要创建UUID,我们建议使用Node的内置UUIDv4生成器。
const { randomUUID } = require('crypto');
const schema = new mongoose.Schema({
docId: {
type: 'UUID',
default: () => randomUUID()
}
});
Getters
Getters are like virtuals for paths defined in your schema. 对于在您的模式中定义的路径,Getter就像是虚拟的。For example, let's say you wanted to store user profile pictures as relative paths and then add the hostname in your application. 例如,假设您希望将用户配置文件图片存储为相对路径,然后在应用程序中添加主机名。Below is how you would structure your 以下是您将如何构建userSchema
:userSchema
:
const root = 'https://s3.amazonaws.com/mybucket';
const userSchema = new Schema({
name: String,
picture: {
type: String,
get: v => `${root}${v}`
}
});
const User = mongoose.model('User', userSchema);
const doc = new User({ name: 'Val', picture: '/123.png' });
doc.picture; // 'https://s3.amazonaws.com/mybucket/123.png'
doc.toObject({ getters: false }).picture; // '/123.png'
Generally, you only use getters on primitive paths as opposed to arrays or subdocuments. 通常,您只在基元路径上使用getter,而不是数组或子文档。Because getters override what accessing a Mongoose path returns, declaring a getter on an object may remove Mongoose change tracking for that path.因为getter覆盖了访问Mongoose路径返回的内容,所以在对象上声明getter可能会删除该路径的Mongoose更改跟踪。
const schema = new Schema({
arr: [{ url: String }]
});
const root = 'https://s3.amazonaws.com/mybucket';
// Bad, don't do this!
schema.path('arr').get(v => {
return v.map(el => Object.assign(el, { url: root + el.url }));
});
// Later
doc.arr.push({ key: String });
doc.arr[0]; // 'undefined' because every `doc.arr` creates a new array!因为每个`doc.arr`都会创建一个新的数组!
Instead of declaring a getter on the array as shown above, you should declare a getter on the 您应该在url
string as shown below. url
字符串上声明一个getter,而不是像上面所示那样在数组上声明getter。If you need to declare a getter on a nested document or array, be very careful!如果您需要在嵌套文档或数组上声明getter,请非常小心!
const schema = new Schema({
arr: [{ url: String }]
});
const root = 'https://s3.amazonaws.com/mybucket';
// Good, do this instead of declaring a getter on `arr`很好,这样做,而不是在`arr`上声明getter
schema.path('arr.0.url').get(v => `${root}${v}`);
Schemas架构
To declare a path as another schema, set 要将一个路径声明为另一个架构,请将type
to the sub-schema's instance.type
设置为子模式的实例。
To set a default value based on the sub-schema's shape, simply set a default value, and the value will be cast based on the sub-schema's definition before being set during document creation.要根据子架构的形状设置默认值,只需设置一个默认值,在文档创建过程中设置之前,该值将基于子架构的定义进行强制转换。
const subSchema = new mongoose.Schema({
// some schema definition here这里有一些架构定义
});
const schema = new mongoose.Schema({
data: {
type: subSchema,
default: {}
}
});
Creating Custom Types创建自定义类型
Mongoose can also be extended with custom SchemaTypes. Mongoose还可以使用自定义SchemaTypes进行扩展。Search the plugins site for compatible types like mongoose-long, mongoose-int32, and mongoose-function.在插件网站上搜索兼容的类型,如mongoose-long、mongoose-int32和mongoose-function。
Read more about creating custom SchemaTypes here.请在此处阅读有关创建自定义SchemaTypes的更多信息。
The `schema.path()` Functionschema.path()
函数
The schema.path()
function returns the instantiated schema type for a given path.schema.path()
函数返回给定路径的实例化模式类型。
const 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: ...
*/
You can use this function to inspect the schema type for a given path, including what validators it has and what the type is.您可以使用此函数来检查给定路径的模式类型,包括它有什么验证器以及类型是什么。
Further Reading进一步阅读
Next Up下一步
Now that we've covered 现在我们已经介绍了SchemaTypes
, let's take a look at Connections.SchemaTypes
,让我们来看看连接。