Mongoose -- Schemas Models Documents

Schemas

Mongoose中,所有的東西都由Schemas開始。schema相當於是MongoDB的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
  }
});

上面的例子中,屬性名後面是屬性的類型,Schema允許的類型包括:

String
Number
Date
Buffer
Boolean
Mixed
ObjectId
Array

schema不僅可以用來定義文檔的結構和屬性,而且還可以用來定義實例方法,靜態方法,索引,生命週期鉤子方法,這些將在下文詳細說明。

接下來,我們需要使用Schema來生成一個Model。

var Blog = mongoose.model('Blog', blogSchema);

實例方法
關鍵字:Schema.methods

實例方法可以使用Schema來定義。

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

Model靜態方法
關鍵字:Schema.statics

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

索引

不太懂…附上原文吧。
這裏寫圖片描述

虛擬屬性

虛擬屬性允許我們創建一個在MongoDB中不存在的屬性。

personSchema.virtual('fullName').get(function () {
  return this.name.first + ' ' + this.name.last;
});

這樣,我們就可以訪問實例的fullName屬性了,但其實這個屬性在數據庫中並不存在。

同時,給fullName我們還可以設置set:

personSchema.virtual('fullName').
  get(function() { return this.name.first + ' ' + this.name.last; }).
  set(function(v) {
    this.name.first = v.substr(0, v.indexOf(' '));
    this.name.last = v.substr(v.indexOf(' ') + 1);
  });

axl.fullName = 'William Rose'; // Now `axl.name.first` is "William"

這樣,當我們設置fullName時,first name和last name也將會被設置。

Options

當我們新建一個Schema的時候,第一個參數可以規定Schema的數據結構(key: type),第二個參數可以定義可選options;如果定義的時候省略第二個參數,則可以使用set方法。

代碼如下:

new Schema({..}, options);

// or

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

可以選擇的options包括:

autoIndex
capped
collection
emitIndexErrors
id
_id
minimize
read
safe
shardKey
strict
toJSON
toObject
typeKey
validateBeforeSave
versionKey
skipVersioning
timestamps
retainKeyOrder

詳情可見:
http://mongoosejs.com/docs/guide.html#autoIndex

Models

var schema = new mongoose.Schema({ name: 'string', size: 'string' });
var Tank = mongoose.model('Tank', schema);

新建文檔

文檔就是Model的實例,有兩種方式可以將數據保存到數據庫。

var Tank = mongoose.model('Tank', yourSchema);

var small = new Tank({ size: 'small' });
small.save(function (err) {
  if (err) return handleError(err);
  // saved!
})

// or

Tank.create({ size: 'small' }, function (err, small) {
  if (err) return handleError(err);
  // saved!
})

注意:如果不建立mongoose的連接,數據是無法保存的。每個Model都有一個綁定的連接。當開發者調用方法mongoose.model()的時候,這個Model將會使用默認的mongoose連接。

mongoose.connect('localhost', 'gettingstarted');

如果你建立了一個常用的連接,可以用這個連接來創建model:

var connection = mongoose.createConnection('mongodb://localhost:27017/test');
var Tank = connection.model('Tank', yourSchema);

查詢

查詢方法包括: find, findById, findOne, where。

Tank.find({ size: 'small' }).where('createdDate').gt(oneYearAgo).exec(callback);

具體將在後文介紹。

刪除

Tank.remove({ size: 'large' }, function (err) {
  if (err) return handleError(err);
  // removed!
});

更新

更新方法:findOneAndUpdate

Documents

更新方法

Tank.findById(id, function (err, tank) {
  if (err) return handleError(err);

  tank.size = 'large'; // or tank.set({ size: 'large' });
  tank.save(function (err, updatedTank) {
    if (err) return handleError(err);
    res.send(updatedTank);
  });
});

上面這個方法,會返回這個查找到的tank實例,如果我們不需要查找功能,只需要更新,則可以使用下面這個方法:

Tank.update({ _id: id }, { $set: { size: 'large' }}, callback);

如果我們需要返回實例,下面這個方法也是一個很好的選擇:

Tank.findByIdAndUpdate(id, { $set: { size: 'large' }}, { new: true }, function (err, tank) {
  if (err) return handleError(err);
  res.send(tank);
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章