SchemaType


SchemaType()

參數 (Parameters)

SchemaType 建構函式。請直接實例化 SchemaType。Mongoose 會自動將您的模式路徑轉換為 SchemaTypes。

範例

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

SchemaType.cast()

參數 (Parameters)
  • 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()

參數 (Parameters)
  • [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()

參數 (Parameters)
  • getter «函式»
傳回
  • «this»

為此模式類型的所有實例附加 getter。

範例

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

SchemaType.prototype.cast()

參數 (Parameters)
  • value «物件» 要轉換的值

  • doc «文件» 觸發轉換的文件

  • init «布林值»

Mongoose 用來將任意值轉換為此 SchemaType 的函式。


SchemaType.prototype.castFunction()

參數 (Parameters)
  • 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()

參數 (Parameters)
  • val «函式|any» 要設定的預設值

傳回
  • «Any,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

預設值可以是傳回要用作預設值的 functions,也可以是文字值本身。無論如何,該值會在文件建立期間設定之前,根據其模式類型進行轉換。

範例

// 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()

參數 (Parameters)
  • value «Any»
  • callback «函式»
  • scope «物件»
  • [options] «物件»
    • [options.path] «字串»
傳回
  • «Any» 如果沒有驗證器,則傳回呼叫 fn 的輸出,否則不傳回任何值

使用為此 SchemaType 宣告的驗證器執行 value 的驗證。


SchemaType.prototype.get()

參數 (Parameters)
  • 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 文件傳輸到您看到的值。

假設您正在儲存信用卡號碼,並且您希望對 mongoose 使用者隱藏除了最後 4 位數字之外的所有內容。您可以透過以下方式定義 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()

參數 (Parameters)
  • bool «布林值»
傳回
  • «SchemaType» this
請參閱

將此路徑定義為不可變。除非父文件具有 isNew: true,否則 Mongoose 會阻止您變更不可變路徑。

範例

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()

參數 (Parameters)
  • 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

類型
  • «property»

如果此 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

類型
  • «property»

此 SchemaType 在模式中的路徑。

範例

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

SchemaType.prototype.ref()

參數 (Parameters)
  • ref «字串|模型|函式» 模型名稱、模型 或傳回模型名稱或模型的函式。

傳回
  • «SchemaType» this

設定此路徑參照的模型。這是 populate 查看以判斷應查詢的外部集合的選項。

範例

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()

參數 (Parameters)
  • required «布林值|函式|物件» 啟用/停用驗證器,或傳回必要布林值的函式,或選項物件

    • [options.isRequired] «布林值|函式» 啟用/停用驗證器,或傳回必要布林值的函式

    • [options.ErrorConstructor] «函式» 自訂錯誤建構函式。建構函式會接收 1 個參數,即包含驗證器屬性的物件。

  • [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(也就是說,如果該值既不是 null 也不是 undefined),則該值滿足必要驗證器。但是,大多數內建的 mongoose 模式類型會覆寫預設的 checkRequired 函式


SchemaType.prototype.select()

參數 (Parameters)
  • 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()

參數 (Parameters)
  • 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 中。電子郵件是一個字串,您希望將其正規化為小寫,以避免一個電子郵件有多個帳戶 - 例如,否則,avenue@q.com 可以透過 avenue@q.comAvEnUe@Q.CoM 註冊 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: 'AVENUE@Q.COM'});
console.log(user.email); // 'avenue@q.com'

// or
const user = new User();
user.email = 'Avenue@Q.com';
console.log(user.email); // 'avenue@q.com'
User.updateOne({ _id: _id }, { $set: { email: 'AVENUE@Q.COM' } }); // update to 'avenue@q.com'

如您在上面看到的,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 中,當使用 this 作為查詢依 name 查詢時,setter 也會執行。

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()

參數 (Parameters)
  • bool «布林值»
傳回
  • «SchemaType» this

宣告稀疏索引。

範例

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

SchemaType.prototype.text()

參數 (Parameters)
  • bool «布林值»
傳回
  • «SchemaType» this

宣告全文索引。

範例

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

SchemaType.prototype.transform()

參數 (Parameters)
  • 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()

參數 (Parameters)
  • bool «布林值»
傳回
  • «SchemaType» this

宣告唯一索引。

範例

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

注意:違反限制會在儲存時從 MongoDB 傳回 E11000 錯誤,而不是 Mongoose 驗證錯誤。


SchemaType.prototype.validate()

參數 (Parameters)
  • obj «RegExp|函式|物件» 驗證器函式或描述選項的雜湊

    • [obj.validator] «函式» 驗證器函式。如果驗證器函式傳回 undefined 或真值,則驗證成功。如果它傳回假值 (除了 undefined) 或拋出錯誤,則驗證失敗。

    • [obj.message] «字串|函式» 可選的錯誤訊息。如果是函式,則應以字串形式傳回錯誤訊息

    • [obj.propsParameter=false] «布林值» 如果為 true,Mongoose 會將驗證器屬性物件(包含 validator 函式、message 等)作為驗證器函式的第 2 個引數傳遞。預設會停用此設定,因為許多驗證器依賴位置引數,因此開啟此設定可能會導致外部驗證器出現無法預測的行為。

  • [errorMsg] «字串|函式» 可選的錯誤訊息。如果是函式,則應以字串形式傳回錯誤訊息

  • [type] «字串» 可選的驗證器類型

傳回
  • «SchemaType» this

為此文件路徑新增驗證器。

驗證器始終會接收要驗證的值作為其第一個引數,並且必須傳回 Boolean。傳回 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()

參數 (Parameters)
  • validators «Array<RegExp|Function|Object>»

為此文件路徑新增多個驗證器。為每個驗證器元素呼叫 validate()


SchemaType.prototype.validators

類型
  • «property»

Mongoose 應執行以驗證此 SchemaType 路徑上屬性的驗證器。

範例

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

SchemaType.set()

參數 (Parameters)
  • option «String» 您想要設定的選項名稱(例如:trim、lowercase 等)

  • value «Any» 您想要設定的選項值。

傳回
  • «void,void»

為此 schema 類型設定預設選項。

範例

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