# 模式(schemas)
> 原文:[Schemas](http://mongoosejs.com/docs/guide.html)
> 翻譯:小蝦米(QQ:509129)
## schemas
> 如果你還沒有開始,請花一分鐘閱讀[快速入門](http://mongoosejs.com/docs/index.html)學習Mongoose 是如何工作的。如果你是從3.x遷移到4.x,請花一點時間來閱讀[遷移指南](http://mongoosejs.com/docs/migration.html)。
### 定義你的schema
Mongoose的一切都始于一個Schema。每個schema映射到MongoDB的集合(collection)和定義該集合(collection)中的文檔的形式。
```
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var blogSchema = new Schema({
title: String,
author: String,
body: String,
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
hidden: Boolean,
meta: {
votes: Number,
favs: Number
}
});
```
如果您想稍后添加額外的鍵(keys),使用[Schema#add](http://mongoosejs.com/docs/api.html#schema_Schema-add)方法。
在我們的blogSchema每個key在我們的文件將被轉換為相關[SchemaType](http://mongoosejs.com/docs/api.html#schematype_SchemaType)定義一個屬性。例如,我們定義了一個標題(title)將被轉換為[字符串(String)](http://mongoosejs.com/docs/api.html#schema-string-js)的 SchemaType 并將日期(date)轉換為日期的 SchemaType 。鍵(keys)也可以被指定嵌套的對象,包含進一步的鍵/類型定義(例如,上面的 `meta`屬性)。
允許使用的SchemaTypes:
- String
- Number
- Date
- Buffer
- Boolean
- Mixed
- ObjectId
- Array
閱讀更多關于他們在[這里](http://mongoosejs.com/docs/schematypes.html)。
Schemas不僅定義了文檔和屬性的結構,還定義了文檔[實例方法](http://mongoosejs.com/docs/guide.html#methods)、靜態[模型方法](http://mongoosejs.com/docs/guide.html#statics)、[復合索引](http://mongoosejs.com/docs/guide.html#indexes)和文檔被稱為[中間件](http://mongoosejs.com/docs/middleware.html)的生命周期鉤子。
### 創建一個模型
使用我們的schema定義,我們需要將我們的blogschema轉成我們可以用的模型。為此,我們通過`mongoose.model(modelName, schema)`:
```
var Blog = mongoose.model('Blog', blogSchema);
// ready to go!
```
### 實例方法
模型的實例是[文檔(documents)](http://mongoosejs.com/docs/documents.html)。文檔有許多自己[內置的實例方法](http://mongoosejs.com/docs/api.html#document-js)。我們也可以定義我們自己的自定義文檔實例方法。
```
// define a schema
var animalSchema = new Schema({ name: String, type: String });
// assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function(cb) {
return this.model('Animal').find({ type: this.type }, cb);
};
```
現在我們所有的animal的實例有一個`findsimilartypes`方法可用。
```
var Animal = mongoose.model('Animal', animalSchema);
var dog = new Animal({ type: 'dog' });
dog.findSimilarTypes(function(err, dogs) {
console.log(dogs); // woof
});
```
> 重寫默認的mongoose文檔方法可能會導致不可預測的結果。[看到更多的細節](http://mongoosejs.com/docs/api.html#schema_Schema.reserved)。
### 靜態方法(Statics)
給一個模型添加靜態方法的也是很簡單。繼續我們的`animalschema`:
```
// assign a function to the "statics" object of our animalSchema
animalSchema.statics.findByName = function(name, cb) {
return this.find({ name: new RegExp(name, 'i') }, cb);
};
var Animal = mongoose.model('Animal', animalSchema);
Animal.findByName('fido', function(err, animals) {
console.log(animals);
});
```
### 查詢助手
您還可以像實例方法那樣添加查詢輔助功能,這是,但對于mongoose的查詢。查詢輔助方法可以讓你擴展mongoose鏈式查詢生成器API。
```
animalSchema.query.byName = function(name) {
return this.find({ name: new RegExp(name, 'i') });
};
var Animal = mongoose.model('Animal', animalSchema);
Animal.find().byName('fido').exec(function(err, animals) {
console.log(animals);
});
```
### 索引(Indexes)
MongoDB支持 [secondary indexes](http://docs.mongodb.org/manual/indexes/) 。與 mongoose,我們定義這些indexes在我們的Schema的在路徑級別或schema級別。在創建[復合索引](http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeys)時,在 schema 級別上定義索引是必要的。
> 譯者注:[普通索引(index)](http://mongoosejs.com/docs/api.html#schematype_SchemaType-index),[唯一索引(unique)](http://mongoosejs.com/docs/api.html#schematype_SchemaType-unique),[稀疏索引](http://mongoosejs.com/docs/api.html#schematype_SchemaType-sparse),[時效索引(expires)](http://mongoosejs.com/docs/api.html#schema_date_SchemaDate-expires)
```
var animalSchema = new Schema({
name: String,
type: String,
tags: { type: [String], index: true } // field level
});
animalSchema.index({ name: 1, type: -1 }); // schema level
```
> 當應用程序啟動時,Mongoose為你的schema定義的每個索引自動調用`ensureindex`。Mongoose會按照每個索引的順序調用ensureindex,并在模型上發出一個`'index'`事件,當所有的`ensureindex`調用返回成功或當時有一個錯誤返回。雖然很好的開發,建議這種行為禁用在生產中,因為索引創建可以導致一個[顯著的性能影響](http://docs.mongodb.org/manual/core/indexes/#index-creation-operations)。通過設置schema的`autoIndex`選項為`false`,或對全局連接的設置選項`config.autoindex`為`false`。
```
mongoose.connect('mongodb://user:pass@localhost:port/database', { config: { autoIndex: false } });
// or
mongoose.createConnection('mongodb://user:pass@localhost:port/database', { config: { autoIndex: false } });
// or
animalSchema.set('autoIndex', false);
// or
new Schema({..}, { autoIndex: false });
```
查看[Model#ensureIndexes](http://mongoosejs.com/docs/api.html#model_Model.ensureIndexes) 方法。
### 虛擬屬性
[虛擬屬性](http://mongoosejs.com/docs/api.html#schema_Schema-virtual) 是文檔屬性,您可以獲取和設置但不保存到MongoDB。用于格式化或組合字段,從而制定者去組成一個單一的值為存儲多個值是有用的。
```
// define a schema
var personSchema = new Schema({
name: {
first: String,
last: String
}
});
// compile our model
var Person = mongoose.model('Person', personSchema);
// create a document
var bad = new Person({
name: { first: 'Walter', last: 'White' }
});
```
假設我們想打印bad的全名。我們可以這樣做:
```
console.log(bad.name.first + ' ' + bad.name.last); // Walter White
```
或者我們可以在personschema定義 [虛擬屬性的getter](http://mongoosejs.com/docs/api.html#virtualtype_VirtualType-get),這樣我們不需要每次寫出這個字符串的拼接:
```
personSchema.virtual('name.full').get(function () {
return this.name.first + ' ' + this.name.last;
});
```
現在,我們進入我們的虛擬”的`"name.full"`資源的時候,我們將調用getter函數的返回值:
```
console.log('%s is insane', bad.name.full); // Walter White is insane
```
注意,如果產生的記錄轉換為一個對象或JSON,virtuals不包括默認。通過`virtuals`:`true`是`toobject()`或`tojson()`他們返回值。
這也是不錯的,能夠通過`this.name.full`設置`this.name.first`和`this.name.last`。例如,如果我們想respectively改變`bad`的`name.first`和`name.last`為`'Breaking'`和`'Bad'`,只需要:
```
bad.name.full = 'Breaking Bad';
```
Mongoose讓你這樣做也是通過[虛擬屬性的setter](http://mongoosejs.com/docs/api.html#virtualtype_VirtualType-set):
```
personSchema.virtual('name.full').set(function (name) {
var split = name.split(' ');
this.name.first = split[0];
this.name.last = split[1];
});
...
mad.name.full = 'Breaking Bad';
console.log(mad.name.first); // Breaking
console.log(mad.name.last); // Bad
```
`[虛擬屬性的setter` 在其他驗證之前使用。因此,上面的例子仍然可以工作,即使第一個和最后一個name字段是必需的。
只有非虛擬屬性工作作為查詢的一部分和字段選擇。
### 選項(Options)
Schemas有幾個可配置的選項,可以直接傳遞給構造函數或設置:
```
new Schema({..}, options);
// or
var schema = new Schema({..});
schema.set(option, value);
```
有效的選項:
- [autoIndex](http://mongoosejs.com/docs/guide.html#autoIndex)
- [capped](http://mongoosejs.com/docs/guide.html#capped)
- [collection](http://mongoosejs.com/docs/guide.html#collection)
- [emitIndexErrors](http://mongoosejs.com/docs/guide.html#emitIndexErrors)
- [id](http://mongoosejs.com/docs/guide.html#id)
- [\_id](http://mongoosejs.com/docs/guide.html#_id)
- [minimize](http://mongoosejs.com/docs/guide.html#minimize)
- [read](http://mongoosejs.com/docs/guide.html#read)
- [safe](http://mongoosejs.com/docs/guide.html#safe)
- [shardKey](http://mongoosejs.com/docs/guide.html#shardKey)
- [strict](http://mongoosejs.com/docs/guide.html#strict)
- [toJSON](http://mongoosejs.com/docs/guide.html#toJSON)
- [toObject](http://mongoosejs.com/docs/guide.html#toObject)
- [typeKey](http://mongoosejs.com/docs/guide.html#typeKey)
- [validateBeforeSave](http://mongoosejs.com/docs/guide.html#validateBeforeSave)
- [versionKey](http://mongoosejs.com/docs/guide.html#versionKey)
- [skipVersioning](http://mongoosejs.com/docs/guide.html#versionKey)
- [timestamps](http://mongoosejs.com/docs/guide.html#versionKey)
#### 選項: autoIndex
在應用程序啟動時,Mongoose在你的Schema為每一個索引聲明發送一個`ensureIndex`命令。在Mongoose V3版本時,索引是默認在后臺創建。如果你想禁用自動創建和手動創建索引時,將你的Schemas自動索引(autoIndex)選項設置為`false`和在你的模型使用`ensureindexes`方法。
```
var schema = new Schema({..}, { autoIndex: false });
var Clock = mongoose.model('Clock', schema);
Clock.ensureIndexes(callback);
```
#### 選項: bufferCommands
默認情況下,mongoose緩沖命令一直存在直到驅動設法重新連接。禁用緩沖,設置`buffercommands`為`false`。
```
var schema = new Schema({..}, { bufferCommands: false });
```
#### 選項: capped
Mongoose支持 MongoDBs [capped](http://www.mongodb.org/display/DOCS/Capped+Collections)集合。指定的MongoDB集合被封頂、設置封頂(capped)選項為文檔的最大[字節](http://www.mongodb.org/display/DOCS/Capped+Collections#CappedCollections-size.)數。
```
new Schema({..}, { capped: 1024 });
```
capped選項也可以設置一個對象,如果你想通過附加選項,像[Max](http://www.mongodb.org/display/DOCS/Capped+Collections#CappedCollections-max)或[autoindexid](http://www.mongodb.org/display/DOCS/Capped+Collections#CappedCollections-autoIndexId)。在這種情況下,您必須顯式地通過size選項。
```
new Schema({..}, { capped: { size: 1024, max: 1000, autoIndexId: true } });
```
#### 選項: collection
Mongoose默認情況下通過模型名稱的`utils.tocollectionname`方法產生的集合名稱。這種方法復數名稱。設置此選項,如果您需要不同的名稱集合。
```
var dataSchema = new Schema({..}, { collection: 'data' });
```
#### 選項: emitIndexErrors
默認情況下,mongoose會建立您在您的模式中指定的任何索引,并在模型中發出一個'index'事件,返回成功或錯誤。
```
MyModel.on('index', function(error) {
/* If error is truthy, index build failed */
});
```
然而,這使得它很難捕捉當您的索引建立失敗。`emitIndexErrors`選項可是是你輕松看到索引建立失敗。如果此選項打開,當索引建立失敗時mongoose會同時在模型上發出一個`'error'`事件。
```
MyModel.schema.options.emitIndexErrors; // true
MyModel.on('error', function(error) {
// gets an error whenever index build fails
});
```
如果一個錯誤事件被觸發并沒有聽眾,Node.js的內置事件拋出一個異常,所以很容易配置快速失敗應用程序時的索引構建失敗。
#### 選項: id
Mongoose將你schemas id virtual getter 默認返回的文檔\_id場轉換為字符串,或者ObjectIds,它的哈希字符串。如果你不想要一個Iid getter加到你的schema,你可以它在schema構建的時通過這個選項禁用。
```
// default behavior
var schema = new Schema({ name: String });
var Page = mongoose.model('Page', schema);
var p = new Page({ name: 'mongodb.org' });
console.log(p.id); // '50341373e894ad16347efe01'
// disabled id
var schema = new Schema({ name: String }, { id: false });
var Page = mongoose.model('Page', schema);
var p = new Page({ name: 'mongodb.org' });
console.log(p.id); // undefined
```
#### 選項: \_id
Mongoose默認分配你的每個模式一個\_id字段如果沒有一個傳遞到[模式](http://mongoosejs.com/docs/api.html#schema-js)構造函數。類型分配一個[objectID](http://mongoosejs.com/docs/api.html#schema_Schema.Types)配合MongoDB的默認行為。如果你不想要一個\_id加到你的模式時,你可以使用這個選項禁用它。
您只能在子文檔中使用此選項。Mongoose不能保存文檔而不知道其id,所以你會保存一個沒有\_id文檔會得到一個錯誤。
```
// default behavior
var schema = new Schema({ name: String });
var Page = mongoose.model('Page', schema);
var p = new Page({ name: 'mongodb.org' });
console.log(p); // { _id: '50341373e894ad16347efe01', name: 'mongodb.org' }
// disabled _id
var childSchema = new Schema({ name: String }, { _id: false });
var parentSchema = new Schema({ children: [childSchema] });
var Model = mongoose.model('Model', parentSchema);
Model.create({ children: [{ name: 'Luke' }] }, function(error, doc) {
// doc.children[0]._id will be undefined
});
```
#### 選項: minimize
Mongoose,默認情況下,“minimize”模式通過刪除空對象。
```
var schema = new Schema({ name: String, inventory: {} });
var Character = mongoose.model('Character', schema);
// will store `inventory` field if it is not empty
var frodo = new Character({ name: 'Frodo', inventory: { ringOfPower: 1 }});
Character.findOne({ name: 'Frodo' }, function(err, character) {
console.log(character); // { name: 'Frodo', inventory: { ringOfPower: 1 }}
});
// will not store `inventory` field if it is empty
var sam = new Character({ name: 'Sam', inventory: {}});
Character.findOne({ name: 'Sam' }, function(err, character) {
console.log(character); // { name: 'Sam' }
});
```
這種行為可以通過設置minimize選項為false。它將存儲空的對象。
```
var schema = new Schema({ name: String, inventory: {} }, { minimize: false });
var Character = mongoose.model('Character', schema);
// will store `inventory` if empty
var sam = new Character({ name: 'Sam', inventory: {}});
Character.findOne({ name: 'Sam' }, function(err, character) {
console.log(character); // { name: 'Sam', inventory: {}}
});
```
#### 選項: read
允許設置[query#read](http://mongoosejs.com/docs/api.html#query_Query-read) 選項在模式層面,為我們提供一種方法來使用默認值[ReadPreferences](http://docs.mongodb.org/manual/applications/replication/#replica-set-read-preference)為模型的所有查詢。
```
var schema = new Schema({..}, { read: 'primary' }); // also aliased as 'p'
var schema = new Schema({..}, { read: 'primaryPreferred' }); // aliased as 'pp'
var schema = new Schema({..}, { read: 'secondary' }); // aliased as 's'
var schema = new Schema({..}, { read: 'secondaryPreferred' }); // aliased as 'sp'
var schema = new Schema({..}, { read: 'nearest' }); // ali
```
每個首選的別名允許替代而不是必須輸入'secondaryPreferred'并得到拼寫錯誤,我們可以簡單地通過'sp'。
讀選項還允許我們指定標記集。這些告訴[驅動程序](https://github.com/mongodb/node-mongodb-native/)的副本集的成員應該嘗試讀取。閱讀更多關于標簽集[這里](http://docs.mongodb.org/manual/applications/replication/#tag-sets)和[這里](http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences)。
注意:您也可以指定驅動程序讀取優先策略選擇當連接時:
```
// pings the replset members periodically to track network latency
var options = { replset: { strategy: 'ping' }};
mongoose.connect(uri, options);
var schema = new Schema({..}, { read: ['nearest', { disk: 'ssd' }] });
mongoose.model('JellyBean', schema);
```
#### 選項: safe
這個選項是通過與MongoDB所有操作并指定如果錯誤應該回到我們的回調以及調寫行為。
```
var safe = true;
new Schema({ .. }, { safe: safe });
```
默認設置為true應用為所有模式,可以保證任何發生的錯誤被傳遞回我們的回調函數。通過設置安全的東西像`{ j: 1, w: 2, wtimeout: 10000 }`,我們可以保證寫致力于MongoDB journal (j: 1),至少有2個副本 (w: 2),并寫會超時如果需要超過10秒 (wtimeout: 10000)。錯誤仍然會被傳遞給我們的回調。
注:在3.6.x,你也需要把[版本](http://mongoosejs.com/docs/guide.html#versionKey)刪掉。在 3.7.x 及以上版本會自動被禁用當安全設置為false。
\*\*注:此設置將覆蓋任何設置指定通過傳遞數據庫選項,同時[創建一個連接](http://mongoosejs.com/docs/api.html#index_Mongoose-createConnection)。
還有其他寫的問題,如`{ w: "majority" }`。看MongoDB[文檔](http://www.mongodb.org/display/DOCS/getLastError+Command)詳情。
```
var safe = { w: "majority", wtimeout: 10000 };
new Schema({ .. }, { safe: safe });
```
#### 選項: shardKey
shardkey選項是用來當我們有一個分片的MongoDB架構。每個分片集提供一個shard key必須存在于所有的插入/更新操作。我們只需要設置此模式選項相同的shard key,我們將所有設置。
```
new Schema({ .. }, { shardKey: { tag: 1, name: 1 }})
```
> 注意,Mongoose不發送`shardcollection`命令給你。你必須配置你自己的分片。
#### 選項: strict
嚴格選項(默認啟用),確保傳遞給我們的模型構造函數的值沒有被指定在我們的模式中,不會被保存到數據庫中。
```
var thingSchema = new Schema({..})
var Thing = mongoose.model('Thing', thingSchema);
var thing = new Thing({ iAmNotInTheSchema: true });
thing.save(); // iAmNotInTheSchema is not saved to the db
// set to false..
var thingSchema = new Schema({..}, { strict: false });
var thing = new Thing({ iAmNotInTheSchema: true });
thing.save(); // iAmNotInTheSchema is now saved to the db!!
```
使用`doc.set()`來設置屬性值這樣也會起作用。
```
var thingSchema = new Schema({..})
var Thing = mongoose.model('Thing', thingSchema);
var thing = new Thing;
thing.set('iAmNotInTheSchema', true);
thing.save(); // iAmNotInTheSchema is not saved to the db
```
這個值可以被覆蓋,在模型實例層通過第二個爾參數:
```
var Thing = mongoose.model('Thing');
var thing = new Thing(doc, true); // enables strict mode
var thing = new Thing(doc, false); // disables strict mode
```
嚴格的選項也可能被設置為“throw”,這將導致錯誤產生,而不是丟棄壞數據。
注意:不要設置為false,除非你有很好的理由。
注:在mongoose v2默認是false的。
注意:任何鍵/值設置在實例上
注意:不管在不在你的模式中存在的任何鍵/值的實例將被忽略,無論模式選項。
```
var thingSchema = new Schema({..})
var Thing = mongoose.model('Thing', thingSchema);
var thing = new Thing;
thing.iAmNotInTheSchema = true;
thing.save(); // iAmNotInTheSchema is never saved to the db
```
#### 選項: toJSON
Exactly the same as the toObject option but only applies when the documents toJSON method is called.
完全一樣的toObject選項,但只適用于當文件tojson方法稱為。
```
var schema = new Schema({ name: String });
schema.path('name').get(function (v) {
return v + ' is my name';
});
schema.set('toJSON', { getters: true, virtuals: false });
var M = mongoose.model('Person', schema);
var m = new M({ name: 'Max Headroom' });
console.log(m.toObject()); // { _id: 504e0cd7dd992d9be2f20b6f, name: 'Max Headroom' }
console.log(m.toJSON()); // { _id: 504e0cd7dd992d9be2f20b6f, name: 'Max Headroom is my name' }
// since we know toJSON is called whenever a js object is stringified:
console.log(JSON.stringify(m)); // { "_id": "504e0cd7dd992d9be2f20b6f", "name": "Max Headroom is my name" }
```
要查看所有可用的toJSON/toObject 選項,讀[這](http://mongoosejs.com/docs/api.html#document_Document-toObject)。
#### 選項: toObject
文檔有一個[toObject](http://mongoosejs.com/docs/api.html#document_Document-toObject)的方法將mongoose文檔轉成成到一個普通的JavaScript對象。此方法接受一些選項。代替這些選項在一個文檔的基礎上,我們可以聲明這里的選項,并將其應用到所有的這個模式文檔為默認。
讓所有的虛函數顯示在你的console.log輸出,設置toObject選項為 { getters: true }:
```
var schema = new Schema({ name: String });
schema.path('name').get(function (v) {
return v + ' is my name';
});
schema.set('toObject', { getters: true });
var M = mongoose.model('Person', schema);
var m = new M({ name: 'Max Headroom' });
console.log(m); // { _id: 504e0cd7dd992d9be2f20b6f, name: 'Max Headroom is my name' }
```
要查看所有可用的toObject選擇,讀[這](http://mongoosejs.com/docs/api.html#document_Document-toObject)。
#### 選項: typeKey
默認情況下,如果在你的模式中你有一個對象‘type’為鍵,mongoose只會把它理解為一種類型聲明。
```
// Mongoose interprets this as 'loc is a String'
var schema = new Schema({ loc: { type: String, coordinates: [Number] } });
```
然而,對于像GeoJSON這樣的應用程序,‘typ’屬性是很重要的。如果你想控制鍵mongoose用找到的類型聲明,設置‘typeKey’模式選項。
```
var schema = new Schema({
// Mongoose interpets this as 'loc is an object with 2 keys, type and coordinates'
loc: { type: String, coordinates: [Number] },
// Mongoose interprets this as 'name is a String'
name: { $type: String }
}, { typeKey: '$type' }); // A '$type' key means this object is a type declaration
```
#### 選項: validateBeforeSave
默認情況下,在將文檔保存到數據庫之前,文檔將自動驗證。這是為了防止保存無效的文檔。如果你想手動處理驗證,能夠保存不通過驗證的對象,您可以設置validatebeforesave為false。
```
var schema = new Schema({ name: String });
schema.set('validateBeforeSave', false);
schema.path('name').validate(function (value) {
return v != null;
});
var M = mongoose.model('Person', schema);
var m = new M({ name: null });
m.validate(function(err) {
console.log(err); // Will tell you that null is not allowed.
});
m.save(); // Succeeds despite being invalid
```
#### 選項: versionKey
versionKey是一個設置在每個文檔上的屬性當第一次被Mongoose創建時。此鍵值包含文檔的內部修訂版。versionkey選項是一個字符串,表示使用版本控制路徑。默認的是`__v`。如果這種與您的應用程序沖突你可以配置:
```
var schema = new Schema({ name: 'string' });
var Thing = mongoose.model('Thing', schema);
var thing = new Thing({ name: 'mongoose v3' });
thing.save(); // { __v: 0, name: 'mongoose v3' }
// customized versionKey
new Schema({..}, { versionKey: '_somethingElse' })
var Thing = mongoose.model('Thing', schema);
var thing = new Thing({ name: 'mongoose v3' });
thing.save(); // { _somethingElse: 0, name: 'mongoose v3' }
```
文檔版本也可以通過設置versionkey為false禁用。不禁用版本除非你[知道你正在做什么](http://aaronheckmann.tumblr.com/post/48943525537/mongoose-v3-part-1-versioning)。
```
new Schema({..}, { versionKey: false });
var Thing = mongoose.model('Thing', schema);
var thing = new Thing({ name: 'no versioning please' });
thing.save(); // { name: 'no versioning please' }
```
#### 選項: skipVersioning
skipversioning允許從versioning扣除路徑(例如,內部的修改不會增加即使這些路徑更新)。不要這樣做,除非你知道你在做什么。對于子文檔,使用完全限定的路徑將此文件包含在父文檔中。
```
new Schema({..}, { skipVersioning: { dontVersionMe: true } });
thing.dontVersionMe.push('hey');
thing.save(); // version is not incremented
```
#### 選項: timestamps
如果設置時間戳,mongoose分配`createdAt`和`updatedAt`字段到你的模式匯總,類型指定為Date。
By default, the name of two fields are createdAt and updatedAt, custom the field name by setting timestamps.createdAt and timestamps.updatedAt.
默認情況下,兩個字段的名字是`createdAt`和`updatedAt`,自定義字段名稱設置`timestamps.createdat`和`timestamps.updatedat`。
```
var thingSchema = new Schema({..}, { timestamps: { createdAt: 'created_at' } });
var Thing = mongoose.model('Thing', thingSchema);
var thing = new Thing();
thing.save(); // `created_at` & `updatedAt` will be included
```
#### 選項: useNestedStrict
在mongoose 4中,`update()`和`findoneandupdate()`只檢查頂層模式的嚴格模式設置。
```
var childSchema = new Schema({}, { strict: false });
var parentSchema = new Schema({ child: childSchema }, { strict: 'throw' });
var Parent = mongoose.model('Parent', parentSchema);
Parent.update({}, { 'child.name': 'Luke Skywalker' }, function(error) {
// Error because parentSchema has `strict: throw`, even though
// `childSchema` has `strict: false`
});
var update = { 'child.name': 'Luke Skywalker' };
var opts = { strict: false };
Parent.update({}, update, opts, function(error) {
// This works because passing `strict: false` to `update()` overwrites
// the parent schema.
});
```
如果你設置`useNestedStrict`為true,mongoose會使用子模式的嚴格選項鑄造更新。
```
var childSchema = new Schema({}, { strict: false });
var parentSchema = new Schema({ child: childSchema },
{ strict: 'throw', useNestedStrict: true });
var Parent = mongoose.model('Parent', parentSchema);
Parent.update({}, { 'child.name': 'Luke Skywalker' }, function(error) {
// Works!
});
```
### Pluggable
模式也可允許我們[打包](http://mongoosejs.com/docs/plugins.html)成可重用的功能[插件](http://plugins.mongoosejs.io/),可以與社區或是你的項目之間共享。
### 下一步
既然我們已經掌握了`Schemas`,讓我們看看[模式類型(SchemaTypes)](http://mongoosejs.com/docs/schematypes.html)。