mongoose 文檔(一) schemas


1、定義shcema

在mongoose里一切都由schema開始。每一個schema對應一個mongoDB collection 並且在那個collection里面定義了documents的模型。

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
  }
});

之后如果你想增加額外的鍵,使用 Schema#add方法

在blogSchema中的每一個key定義了在document中的一個屬性,將轉換為它相關的Schema類型。例如,我們已經定義了的title將轉換為String Schema類型並且date將轉換為Date Schema 類型。鍵也可以指定為嵌套對象包含更多的 key/type 定義(例如上面的'meta'屬性)。

 

合法的Schema 類型是

  • String
  • Number
  • Date
  • Buffer
  • Boolean
  • Mixed
  • ObjectId
  • Array

查看更多

 

Shema不僅定義了document的結構和構造了屬性,還定義了document實例方法、靜態Model方法復合索引和被稱作middleware的document生命周期鈎子。

 

2、創建一個Model

使用schema定義,需要將blogSchema轉換為能夠工作的Model。為此,我們把它傳給

mongoose.model(modelName, schema)

var Blog = mongoose.model('Blog', blogSchema);
// ready to go!

 

3、實例方法

Model的實例是document。document有很多內置的實例方法。我們也可以定義自己的document實例方法。

// 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實例有findSiilarTypes方法 可用。

var Animal = mongoose.model('Animal', animalSchema);
var dog = new Animal({ type: 'dog' });

dog.findSimilarTypes(function (err, dogs) {
  console.log(dogs); // woof
});

重新默認的mongoose document方法可以會導致不可預知的結果。

 

4、靜態

在model中添加靜態方法很簡單。繼續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);
});

 

 

5、索引

MongoDB支持二級索引。在mongoose, at the path level或schema層次定義Schema的索引。當創建復合索引時,在shema定義索引是必要的。

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,當所有ensureIndex調用成功或發生錯誤在model發出index事件。建議在生產中禁止這種行為因為索引創建能夠導致顯著的性能影響。通過給schema設置autoIndex選項為false來禁用行為,或者在connection全局設置選項config.autoIndex為false。

animalSchema.set('autoIndex', false);
// or
new Schema({..}, { autoIndex: false });

 Model#ensureIndexes 方法

 

6、Virtuals

virtual  是你能 get 和 set 但不能保存到 MongoDB 的 document 屬性。getter用於格式化或符合的field,而setter用於de-composing一個單值到多值存儲。

// 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 定義一個 virtual屬性getter, 因此我們不需每次寫這些字符串連接

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

 

主要如果結果記錄轉換為object或者JSON,默認不包括virtual。

 

通過設置 this.name.full 能設置this.name.first和 this.name.last 是令人高興的。例如,我們想要分別改變 bad 的 name.first 和 name.last 為 'Breaking' 和 'bad',可以這樣:

bad.name.full = 'Breaking Bad';

Mongoose也通過它的 virtual property setters讓你這么做

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.first 和name.last fields。

 

作為查詢的一部分和對於field選擇,只有非虛擬屬性有效。

 

7、option

new Schema({..}, options);

// or

var schema = new Schema({..});
schema.set(option, value);

 

有效的選項

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM