mongose學習--Schema、model


·  前言

  Mongoose是MongoDB的一個對象模型工具,基於node-mongodb-native開發。

  初學node.js,之前看了一些博客,決定還是自己從官方文檔入手學習Mongoose,所以本文內容一部分是官方文檔的翻譯內容。留作筆記之用,有所側重,不會大而全。而且隨着理解加深會不斷充實本文內容。

 

  環境說明

  本文實踐是在win10下的mongoDB+Node.js+webstorm的環境上進行的。

 

  connect

  數據庫連接大同小異,以下是官網示例

mongoose.connect('mongodb://user:pass@localhost:port/database');

// replica sets
var uri = 'mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/mydatabase';
mongoose.connect(uri);

// with options
mongoose.connect(uri, options);

// connecting to multiple mongos
var uri = 'mongodb://hostA:27501,hostB:27501';
var opts = { mongos: true };
mongoose.connect(uri, opts);

// optional callback that gets fired when initial connection completed
var uri = 'mongodb://nonexistent.domain:27000';
mongoose.connect(uri, function(error) {
  // if error is truthy, the initial connection failed.
})

 

  以下代碼是本文連接數據庫的方法:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
    console.log('connected');
});

 

  Schema

  在Mongoose里一切都是從Schema開始的,每一個Schema都會映射到MongoDB的一個collection上。Schema定義了collection里documents的模板(或者說是框架)。

  如下代碼定義了一個博客的Schema:

var blogSchema = new Schema({ // Schema頭字母大寫,因為Schema是構造函數
  title:  String,
  author: String,
  body:   String,
  comments: [{ body: String, date: Date }], // 對象數組
  date: { type: Date, default: Date.now }, // 通過default設置默認值
  hidden: Boolean,
  meta: { // 嵌套對象
    votes: Number,
    favs:  Number
  }
});

  如果想對已經定義好的blogSchema添加鍵,可以用如下方法:

blogSchema.add({reprints : Number});

  Schema支持的鍵值類型有String,Number,Date,Buffer,Boolean,Array,Objectld,Mixed。Schema不僅定義document的模板,而且可以定義document的實例方法。

  _id

  在MongoDB中同一個collection里的文檔都必有且唯一的“id”鍵用於唯一標識document,鍵值可為任意類型默認是ObjectId對象。ObjectId的設計初衷是為了分布式,所以不像傳統方法默認增加主鍵。這是一種輕量型設計,不同的機器可以用全局唯一的方法生成。ObjectId存儲空間是12字節,前四個字節是標准紀元時間戳(單位為秒),隱含該document的創建時間(由於大致是按時間順序存儲,故使用id作為索引的效率會很高)。后三個字節是主機唯一標志符,通常是主機名的散列值。接着后兩個字節是進程標識,最后三個字節是自動增加的計數器,確保同一秒內同一主機同一進程的ObjectId是唯一的。以上的生成document的id過程都是客戶端完成的,用以減輕服務器的開銷。

  index

  我們在定義Schema的時候可以定義其索引,一般是多重索引。

  以下代碼是添加索引:

blogSchema.index({blogTitle : 1, reprints : -1});

  這樣就建立了以blogTitel為正序,reprints為逆序的多重索引。

 

   model

  為了使用定義好的Schema,我們需要把blogSchema轉換成我們可以使用的model(其實是把Schema編譯成model,所以對於Schema的一切定義都要在compile之前完成)。也就是說model才是我們可以進行操作的handle。

  以下代碼是編譯model的方法:

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

  這樣我們就獲得了一個名為Blog的model了。生成model的同時MongoDB中對應的collection也被建立了,model的名字是Blog,而collection的名字被默認是model名字的復數也就是blogs(細心的小伙伴會發現不止變復數了,而且字母全部變小寫了,親測是這樣的)。

  官網中有關model()函數的用法如下:

Connection#model(name, [schema], [collection])
Defines or retrieves a model.

Parameters:
name <String> the model name
[schema] <Schema> a schema. necessary when defining a model

[collection] <String> name of mongodb collection (optional) if not given it will be induced from model name

Returns:
<Model> The compiled model

 

  以下代碼是通過model生成document,以及document保存的方法:

var blog01 = new Blog({
    blogTitle : 'The total eclipse of hreat',
    body : '........',
    comments : [{body : "That's awesome", date : new Date()}],
    hidden : false,
    state : {
        favors : 999,
        marks : 999
    }
});
blog01.save(function(err){
    if (err){
        return console.error(err);
    }
    console.log('saved');
})

  真正跑過以上代碼就會發現MongoDB的容錯性很好,以上代碼其實在生成document時漏了一個鍵reprints賦值,但還是可以保存,而且在查詢該條document時reprints這個字段是不會顯示的。另外如果在生成document時,我們把鍵值的名字寫錯了,MongoDB還是可以忽略被輸錯的鍵的,把正確鍵對應的值存起來,忽略錯誤鍵名。

  而且在id上,除了document有id,comments對應的對象數組也會有唯一id,如下圖:

  

  Schema和model的理解

  不同於關系型數據庫,MongoDB作為文檔型數據庫,Scheme、model、collection、document是其中的四大元素。document是MongoDB里的基本存儲單位,collection是眾多同類document的集合。Schema定義了一類document的模板,讓這一類document在數據庫中有一個具體的構成、存儲模式。而Schema僅僅是定義了Document是什么樣子的,至於生成document和對document進行各種操作(增刪改查)則是通過相對應的model來進行的。

  需要說明的是MongoDB中實際上只有collection和document,Schema和model不過是定義和生成前二者過程中的工具而已。

 

  總結

  本文忽略了有關methods的介紹和connection與model之間的切換,主要是自己沒完全搞清楚,搞清楚了會加上

  以下代碼是全文代碼匯總:

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
    console.log('connected');
});
var Schema = mongoose.Schema;
var blogSchema = Schema
({
    blogTitle : String,
    body : String,
    comments : [{body : String, date : Date}],
    hidden : Boolean,
    state : {
        favors : Number,
        marks : Number
    }
});
blogSchema.add({reprints : Number});
blogSchema.index({blogTitel : 1, reprints : -1});
var Blog = mongoose.model('Blog', blogSchema);
var blog01 = new Blog({
    blogTitle : 'The total eclipse of hreat',
    body : '........',
    comments : [{body : "That's awesome", date : new Date()}],
    hidden : false,
    state : {
        favors : 999,
        marks : 999
    },
    reprints : 999
});
blog01.save(function(err){
    if (err){
        return console.error(err);
    }
    console.log('saved');
});

mongoose.connection.close();
View Code

 


免責聲明!

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



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