SchemaTypes

SchemaTypes handle definition of path defaults, validation, getters, setters, field selection defaults for queries, and other general characteristics for Mongoose document properties.SchemaTypes处理路径默认值验证getterssetters查询字段选择默认值的定义,以及Mongoose文档属性的其他一般特征。

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, mongoose.ObjectId !== mongoose.Types.ObjectId. SchemaType与类型不同。换句话说,mongoose.ObjectId !== mongoose.Types.ObjectIdA 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 is a special property in Mongoose schemas. 是Mongoose架构中的一个特殊属性。When Mongoose finds a nested property named type in your schema, Mongoose assumes that it needs to define a SchemaType with the given type.当Mongoose在您的架构中找到一个名为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 type: String, it assumes that you mean asset should be a string, not an object with a property type. 然而,当Mongoose看到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 autopopulate: true in your SchemaType options. 例如,如果您在SchemaType选项中设置autopopulate:truemongoose-autopopulate插件会自动填充路径。Mongoose comes with support for several built-in SchemaType options, like lowercase in the above example.Mongoose支持几个内置的SchemaType选项,比如上面例子中的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 has isNew: true.Mongoose防止您更改不可变的路径,除非父文档具有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 .toLowerCase() on the value:boolean,是否总是对值调用.toLowerCase()
  • uppercase: boolean, whether to always call .toUpperCase() on the value:boolean,是否总是对值调用.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

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 valueOf() function will all result in a CastError once validated, meaning that it will not throw on initialization, only when validated.NaN、转换为NaN的字符串、数组和没有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 global constructor or the string 'Buffer'.要将路径声明为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 doc.markModified(path), passing the path to the Mixed type you just changed.要告诉Mongoose Mixed类型的值已经更改,您需要调用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 driver that is an ObjectId:ObjectId是一种特殊类型,通常用于唯一标识符。以下是如何使用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 true:默认情况下,Mongoose将以下值强制转换为true

  • true
  • 'true'
  • 1
  • '1'
  • 'yes'

Mongoose casts the below values to false:Mongoose将以下值强制转换为false

  • false
  • 'false'
  • 0
  • '0'
  • 'no'

Any other value causes a CastError. 任何其他值都会导致CastErrorYou can modify what values Mongoose converts to true or false using the convertToTrue and convertToFalse properties, which are JavaScript sets.您可以使用convertToTrueconvertToFalse属性修改Mongoose将哪些值转换为truefalse,这两个属性是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. 注意:指定一个空数组相当于MixedThe 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. MongooseMapJavaScript的Map的一个子类。In these docs, we'll use the terms 'map' and MongooseMap interchangeably. 在这些文档中,我们将交替使用术语“映射”和MongooseMapIn 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. 上面的例子没有明确声明githubtwitter为路径,但由于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 $* syntax to populate all elements in a map. Mongoose支持一种特殊的$*语法来填充映射中的所有元素。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 bson.Binary type with a getter that converts the binary to a string when you access it. 在Node.js中,UUID被表示为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-longmongoose-int32mongoose-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,让我们来看看连接