SchemaType


SchemaType()

参数

SchemaType 构造函数。不要直接实例化 SchemaType。Mongoose 会自动将您的模式路径转换为 SchemaTypes。

示例

const schema = new Schema({ name: String });
schema.path('name') instanceof SchemaType; // true

SchemaType.cast()

参数
  • caster «函数|false» 将任意值强制转换为此类型,或者如果强制转换失败则抛出错误

返回
  • «函数»

获取/设置用于将任意值强制转换为此类型的函数。

示例

// Disallow `null` for numbers, and don't try to cast any values to
// numbers, so even strings like '123' will cause a CastError.
mongoose.Number.cast(function(v) {
  assert.ok(v === undefined || typeof v === 'number');
  return v;
});

SchemaType.checkRequired()

参数
  • [fn] «函数» 如果设置,将覆盖当前设置的函数

返回
  • «函数» 输入 fn 或已设置的函数

设置和获取 checkRequired 函数 覆盖所需验证器用来检查值是否通过 required 检查的函数。在单个 SchemaType 上覆盖此函数。

示例

// Use this to allow empty strings to pass the `required` validator
mongoose.Schema.Types.String.checkRequired(v => typeof v === 'string');

SchemaType.get()

参数
  • getter «函数»
返回
  • «this»

为此模式类型的每个实例附加一个 getter。

示例

// Make all numbers round down
mongoose.Number.get(function(v) { return Math.floor(v); });

SchemaType.prototype.cast()

参数
  • value «对象» 要强制转换的值

  • doc «文档» 触发强制转换的文档

  • init «布尔值»

Mongoose 用于将任意值强制转换为此 SchemaType 的函数。


SchemaType.prototype.castFunction()

参数
  • caster «函数|false» 将任意值强制转换为此类型,或者如果强制转换失败则抛出错误

返回
  • «函数»

获取/设置用于将任意值强制转换为此特定模式类型实例的函数。覆盖 SchemaType.cast()

示例

// Disallow `null` for numbers, and don't try to cast any values to
// numbers, so even strings like '123' will cause a CastError.
const number = new mongoose.Number('mypath', {});
number.cast(function(v) {
  assert.ok(v === undefined || typeof v === 'number');
  return v;
});

SchemaType.prototype.default()

参数
  • val «函数|任何» 要设置的默认值

返回
  • «任何,undefined,void» 返回设置的默认值。

为此 SchemaType 设置默认值。

示例

const schema = new Schema({ n: { type: Number, default: 10 })
const M = db.model('M', schema)
const m = new M;
console.log(m.n) // 10

默认值可以是 函数(返回用作默认值的 value),也可以是 value 本身。无论哪种方式,value 都将在文档创建期间设置之前根据其模式类型进行强制转换。

示例

// values are cast:
const schema = new Schema({ aNumber: { type: Number, default: 4.815162342 }})
const M = db.model('M', schema)
const m = new M;
console.log(m.aNumber) // 4.815162342

// default unique objects for Mixed types:
const schema = new Schema({ mixed: Schema.Types.Mixed });
schema.path('mixed').default(function () {
  return {};
});

// if we don't use a function to return object literals for Mixed defaults,
// each document will receive a reference to the same object literal creating
// a "shared" object instance:
const schema = new Schema({ mixed: Schema.Types.Mixed });
schema.path('mixed').default({});
const M = db.model('M', schema);
const m1 = new M;
m1.mixed.added = 1;
console.log(m1.mixed); // { added: 1 }
const m2 = new M;
console.log(m2.mixed); // { added: 1 }

SchemaType.prototype.doValidate()

参数
  • value «任何»
  • callback «函数»
  • scope «对象»
  • [options] «对象»
    • [options.path] «字符串»
返回
  • «任何» 如果没有验证器,则返回调用 fn 的输出,否则不返回任何内容

使用为此 SchemaType 声明的验证器执行 value 的验证。


SchemaType.prototype.get()

参数
  • fn «函数»
返回
  • «SchemaType» this

为此模式类型添加 getter。

示例

function dob (val) {
  if (!val) return val;
  return (val.getMonth() + 1) + "/" + val.getDate() + "/" + val.getFullYear();
}

// defining within the schema
const s = new Schema({ born: { type: Date, get: dob })

// or by retreiving its SchemaType
const s = new Schema({ born: Date })
s.path('born').get(dob)

Getter 允许您在数据从原始 mongodb 文档传输到您看到的值时转换数据的表示形式。

假设您正在存储信用卡号,并且您希望隐藏除最后 4 位之外的所有内容以显示给 mongoose 用户。您可以通过以下方式定义 getter 来做到这一点

function obfuscate (cc) {
  return '****-****-****-' + cc.slice(cc.length-4, cc.length);
}

const AccountSchema = new Schema({
  creditCardNumber: { type: String, get: obfuscate }
});

const Account = db.model('Account', AccountSchema);

Account.findById(id, function (err, found) {
  console.log(found.creditCardNumber); // '****-****-****-1234'
});

Getter 还传递第二个参数,即定义 getter 的模式类型。这允许根据在模式中传递的选项定制行为。

function inspector (val, priorValue, schematype) {
  if (schematype.options.required) {
    return schematype.path + ' is required';
  } else {
    return schematype.path + ' is not';
  }
}

const VirusSchema = new Schema({
  name: { type: String, required: true, get: inspector },
  taxonomy: { type: String, get: inspector }
})

const Virus = db.model('Virus', VirusSchema);

Virus.findById(id, function (err, virus) {
  console.log(virus.name);     // name is required
  console.log(virus.taxonomy); // taxonomy is not
})

SchemaType.prototype.getEmbeddedSchemaType()

返回嵌入的模式类型(如果有)。对于数组、文档数组和映射,getEmbeddedSchemaType() 返回数组元素(或映射元素)的模式类型。对于其他类型,getEmbeddedSchemaType() 返回 undefined

示例

const schema = new Schema({ name: String, tags: [String] });
schema.path('name').getEmbeddedSchemaType(); // undefined
schema.path('tags').getEmbeddedSchemaType(); // SchemaString { path: 'tags', ... }

SchemaType.prototype.immutable()

参数
  • bool «布尔值»
返回
  • «SchemaType» this
查看

将此路径定义为不可变。Mongoose 阻止您更改不可变路径,除非父文档具有 isNew: true

示例

const schema = new Schema({
  name: { type: String, immutable: true },
  age: Number
});
const Model = mongoose.model('Test', schema);

await Model.create({ name: 'test' });
const doc = await Model.findOne();

doc.isNew; // false
doc.name = 'new name';
doc.name; // 'test', because `name` is immutable

Mongoose 还根据 严格模式 阻止使用 updateOne()updateMany() 更改不可变属性。

示例

// Mongoose will strip out the `name` update, because `name` is immutable
Model.updateOne({}, { $set: { name: 'test2' }, $inc: { age: 1 } });

// If `strict` is set to 'throw', Mongoose will throw an error if you
// update `name`
const err = await Model.updateOne({}, { name: 'test2' }, { strict: 'throw' }).
  then(() => null, err => err);
err.name; // StrictModeError

// If `strict` is `false`, Mongoose allows updating `name` even though
// the property is immutable.
Model.updateOne({}, { name: 'test2' }, { strict: false });

SchemaType.prototype.index()

参数
  • options «对象|布尔值|字符串|数字»
返回
  • «SchemaType» this

声明此模式类型的索引选项。

示例

const s = new Schema({ name: { type: String, index: true })
const s = new Schema({ name: { type: String, index: -1 })
const s = new Schema({ loc: { type: [Number], index: 'hashed' })
const s = new Schema({ loc: { type: [Number], index: '2d', sparse: true })
const s = new Schema({ loc: { type: [Number], index: { type: '2dsphere', sparse: true }})
const s = new Schema({ date: { type: Date, index: { unique: true, expires: '1d' }})
s.path('my.path').index(true);
s.path('my.date').index({ expires: 60 });
s.path('my.path').index({ unique: true, sparse: true });

注意

索引默认情况下 在后台创建。如果将 background 设置为 false,MongoDB 将不会执行您发送的任何读写操作,直到索引构建完成。指定 background: false 以覆盖 Mongoose 的默认值。


SchemaType.prototype.isRequired

类型
  • «属性»

如果此 SchemaType 具有必需验证器,则为 true。否则为 false。

示例

const schema = new Schema({ name: { type: String, required: true } });
schema.path('name').isRequired; // true

schema.path('name').required(false);
schema.path('name').isRequired; // false

SchemaType.prototype.path

类型
  • «属性»

此 SchemaType 在模式中的路径。

示例

const schema = new Schema({ name: String });
schema.path('name').path; // 'name'

SchemaType.prototype.ref()

参数
  • ref «字符串|模型|函数» 模型名称、模型 或返回模型名称或模型的函数。

返回
  • «SchemaType» this

设置此路径引用的模型。这是 填充 用于确定要查询的外部集合的选项。

示例

const userSchema = new Schema({ name: String });
const User = mongoose.model('User', userSchema);

const postSchema = new Schema({ user: mongoose.ObjectId });
postSchema.path('user').ref('User'); // Can set ref to a model name
postSchema.path('user').ref(User); // Or a model class
postSchema.path('user').ref(() => 'User'); // Or a function that returns the model name
postSchema.path('user').ref(() => User); // Or a function that returns the model class

// Or you can just declare the `ref` inline in your schema
const postSchema2 = new Schema({
  user: { type: mongoose.ObjectId, ref: User }
});

SchemaType.prototype.required()

参数
  • required «布尔值|函数|对象» 启用/禁用验证器,或返回所需布尔值的函数,或选项对象

    • [options.isRequired] «布尔值|函数» 启用/禁用验证器,或返回所需布尔值的函数

    • [options.ErrorConstructor] «函数» 自定义错误构造函数。构造函数接收一个参数,一个包含验证器属性的对象。

  • [message] «字符串» 可选的自定义错误消息

返回
  • «SchemaType» this
查看

为此 SchemaType 添加必需验证器。验证器使用 unshift() 添加到此 SchemaType 的验证器数组的开头。

示例

const s = new Schema({ born: { type: Date, required: true })

// or with custom error message

const s = new Schema({ born: { type: Date, required: '{PATH} is required!' })

// or with a function

const s = new Schema({
  userId: ObjectId,
  username: {
    type: String,
    required: function() { return this.userId != null; }
  }
})

// or with a function and a custom message
const s = new Schema({
  userId: ObjectId,
  username: {
    type: String,
    required: [
      function() { return this.userId != null; },
      'username is required if id is specified'
    ]
  }
})

// or through the path API

s.path('name').required(true);

// with custom error messaging

s.path('name').required(true, 'grrr :( ');

// or make a path conditionally required based on a function
const isOver18 = function() { return this.age >= 18; };
s.path('voterRegistrationId').required(isOver18);

必需验证器使用 SchemaType 的 checkRequired 函数来确定给定值是否满足必需验证器。默认情况下,如果 val != null(即,如果 value 不是 null 也不为 undefined),则值将满足必需验证器。但是,大多数内置的 mongoose 模式类型会覆盖默认的 checkRequired 函数


SchemaType.prototype.select()

参数
  • val «布尔值»
返回
  • «SchemaType» this

设置此路径的默认 select() 行为。

如果此路径应始终包含在结果中,则设置为 true,如果此路径应默认排除,则设置为 false。此设置可以在查询级别覆盖。

示例

T = db.model('T', new Schema({ x: { type: String, select: true }}));
T.find(..); // field x will always be selected ..
// .. unless overridden;
T.find().select('-x').exec(callback);

SchemaType.prototype.set()

参数
  • fn «函数»
返回
  • «SchemaType» this

为此模式类型添加 setter。

示例

function capitalize (val) {
  if (typeof val !== 'string') val = '';
  return val.charAt(0).toUpperCase() + val.substring(1);
}

// defining within the schema
const s = new Schema({ name: { type: String, set: capitalize }});

// or with the SchemaType
const s = new Schema({ name: String })
s.path('name').set(capitalize);

Setter 允许您在数据到达原始 mongodb 文档或查询之前转换数据。

假设您正在为网站实现用户注册。用户提供电子邮件和密码,这些信息将保存到 mongodb。电子邮件是一个字符串,您需要将其规范化为小写,以避免一个电子邮件拥有多个帐户,例如,否则,[email protected] 可以通过 [email protected][email protected] 注册 2 个帐户。

您可以通过 Mongoose setter 轻松设置电子邮件小写规范化。

function toLower(v) {
  return v.toLowerCase();
}

const UserSchema = new Schema({
  email: { type: String, set: toLower }
});

const User = db.model('User', UserSchema);

const user = new User({email: '[email protected]'});
console.log(user.email); // '[email protected]'

// or
const user = new User();
user.email = '[email protected]';
console.log(user.email); // '[email protected]'
User.updateOne({ _id: _id }, { $set: { email: '[email protected]' } }); // update to '[email protected]'

如上所示,setter 允许您在将数据存储到 MongoDB 或执行查询之前转换数据。

注意:我们也可以使用内置的 lowercase: true SchemaType 选项,而不是定义我们自己的函数。

new Schema({ email: { type: String, lowercase: true }})

Setter 还传递第二个参数,即定义 setter 的模式类型。这允许根据在模式中传递的选项定制行为。

function inspector (val, priorValue, schematype) {
  if (schematype.options.required) {
    return schematype.path + ' is required';
  } else {
    return val;
  }
}

const VirusSchema = new Schema({
  name: { type: String, required: true, set: inspector },
  taxonomy: { type: String, set: inspector }
})

const Virus = db.model('Virus', VirusSchema);
const v = new Virus({ name: 'Parvoviridae', taxonomy: 'Parvovirinae' });

console.log(v.name);     // name is required
console.log(v.taxonomy); // Parvovirinae

您还可以使用 setter 修改文档上的其他属性。如果您在文档上设置属性 name,则 setter 将以 this 作为文档运行。注意,在 mongoose 5 中,setter 还将在使用 name 通过 this 查询时运行。

const nameSchema = new Schema({ name: String, keywords: [String] });
nameSchema.path('name').set(function(v) {
  // Need to check if `this` is a document, because in mongoose 5
  // setters will also run on queries, in which case `this` will be a
  // mongoose query object.
  if (this instanceof Document && v != null) {
    this.keywords = v.split(' ');
  }
  return v;
});

SchemaType.prototype.sparse()

参数
  • bool «布尔值»
返回
  • «SchemaType» this

声明稀疏索引。

示例

const s = new Schema({ name: { type: String, sparse: true } });
s.path('name').index({ sparse: true });

SchemaType.prototype.text()

参数
  • bool «布尔值»
返回
  • «SchemaType» this

声明全文索引。

示例

 const s = new Schema({ name : { type: String, text : true } })
 s.path('name').index({ text : true });

SchemaType.prototype.transform()

参数
  • fn «函数»
返回
  • «SchemaType» this

定义一个自定义函数,用于在将文档转换为 JSON 时转换此路径。

Mongoose 使用一个参数调用此函数:路径的当前 value。然后,Mongoose 将返回值用于 JSON 输出。

示例

const schema = new Schema({
  date: { type: Date, transform: v => v.getFullYear() }
});
const Model = mongoose.model('Test', schema);

await Model.create({ date: new Date('2016-06-01') });
const doc = await Model.findOne();

doc.date instanceof Date; // true

doc.toJSON().date; // 2016 as a number
JSON.stringify(doc); // '{"_id":...,"date":2016}'

SchemaType.prototype.unique()

参数
  • bool «布尔值»
返回
  • «SchemaType» this

声明唯一索引。

示例

const s = new Schema({ name: { type: String, unique: true } });
s.path('name').index({ unique: true });

注意:违反约束会从 MongoDB 返回 E11000 错误,而不是 Mongoose 验证错误。


SchemaType.prototype.validate()

参数
  • obj «正则表达式|函数|对象» 验证器函数,或描述选项的哈希

    • [obj.validator] «函数» 验证器函数。如果验证器函数返回 undefined 或真值,则验证成功。如果它返回 假值(除了 undefined)或抛出错误,则验证失败。

    • [obj.message] «字符串|函数» 可选的错误消息。如果是函数,则应以字符串形式返回错误消息

    • [obj.propsParameter=false] «布尔值» 如果为 true,Mongoose 将验证器属性对象(带有 validator 函数、message 等)作为第二个参数传递给验证器函数。默认情况下,这被禁用,因为许多验证器 依赖于位置参数,因此启用此选项可能会导致外部验证器出现不可预测的行为。

  • [errorMsg] «字符串|函数» 可选的错误消息。如果是函数,则应以字符串形式返回错误消息

  • [type] «字符串» 可选的验证器类型

返回
  • «SchemaType» this

为该文档路径添加验证器。

验证器始终接收要验证的值作为其第一个参数,并且必须返回 布尔值。返回 false 或抛出错误意味着验证失败。

错误消息参数是可选的。如果未传递,将使用 默认的通用错误消息模板

示例

// make sure every value is equal to "something"
function validator (val) {
  return val === 'something';
}
new Schema({ name: { type: String, validate: validator }});

// with a custom error message

const custom = [validator, 'Uh oh, {PATH} does not equal "something".']
new Schema({ name: { type: String, validate: custom }});

// adding many validators at a time

const many = [
    { validator: validator, message: 'uh oh' }
  , { validator: anotherValidator, message: 'failed' }
]
new Schema({ name: { type: String, validate: many }});

// or utilizing SchemaType methods directly:

const schema = new Schema({ name: 'string' });
schema.path('name').validate(validator, 'validation of `{PATH}` failed with value `{VALUE}`');

错误消息模板

以下是受支持的模板关键字列表

  • PATH:触发错误的模式路径。
  • VALUE:分配给触发错误的 PATH 的值。
  • KIND:触发错误的验证属性,例如 required。
  • REASON:导致此错误的错误对象(如果有)。

如果 Mongoose 的内置错误消息模板不够,Mongoose 支持将 message 属性设置为函数。

schema.path('name').validate({
  validator: function(v) { return v.length > 5; },
  // `errors['name']` will be "name must have length 5, got 'foo'"
  message: function(props) {
    return `${props.path} must have length 5, got '${props.value}'`;
  }
});

要绕过 Mongoose 的错误消息并仅复制验证器抛出的错误消息,请执行以下操作

schema.path('name').validate({
  validator: function() { throw new Error('Oops!'); },
  // `errors['name'].message` will be "Oops!"
  message: function(props) { return props.reason.message; }
});

异步验证

Mongoose 支持返回 promise 的验证器。返回 promise 的验证器称为异步验证器。异步验证器并行运行,validate() 将等待所有异步验证器完成。

schema.path('name').validate({
  validator: function (value) {
    return new Promise(function (resolve, reject) {
      resolve(false); // validation failed
    });
  }
});

您可能使用异步验证器从数据库中检索其他文档以进行验证,或满足其他 I/O 绑定验证需求。

验证在 pre('save') 或您手动执行 document#validate 时发生。

如果验证在 pre('save') 期间失败,并且没有传递回调来接收错误,则会对您模型关联的数据库连接发出一个 error 事件,并传递验证错误对象。

const conn = mongoose.createConnection(..);
conn.on('error', handleError);

const Product = conn.model('Product', yourSchema);
const dvd = new Product(..);
dvd.save(); // emits error on the `conn` above

如果您想在模型级别处理这些错误,请向您的模型添加一个 error 监听器,如下所示。

// registering an error listener on the Model lets us handle errors more locally
Product.on('error', handleError);

SchemaType.prototype.validateAll()

参数
  • validators «Array<RegExp|Function|Object>»

为该文档路径添加多个验证器。为验证器中的每个元素调用 validate()


SchemaType.prototype.validators

类型
  • «属性»

Mongoose 应该运行以验证此 SchemaType 路径上的属性的验证器。

示例

const schema = new Schema({ name: { type: String, required: true } });
schema.path('name').validators.length; // 1, the `required` validator

SchemaType.set()

参数
  • option «String» 您想要设置的选项的名称(例如 trim、lowercase 等)

  • value «Any» 您想要设置的选项的值。

返回
  • «void,void»

为该模式类型设置一个默认选项。

示例

// Make all strings be trimmed by default
mongoose.SchemaTypes.String.set('trim', true);