前面的話

  Mongoose是在node.js異步環(huán)境下對mongodb進行便捷操作的對象模型工具。本文將詳細介紹如何使用Mongoose來操作MongoDB

 

NodeJS驅(qū)動

  在介紹Mongoose之前,首先介紹使用NodeJS操作MongoDB的方法

  如果使用程序操作數(shù)據(jù)庫,就要使用MongoDB驅(qū)動。MongoDB驅(qū)動實際上就是為應用程序提供的一個接口,不同的語言對應不同的驅(qū)動,NodeJS驅(qū)動不能應用在其他后端語言中

  首先,安裝mongodb

npm install mongodb

  接著,使用require()方法引入mongodb數(shù)據(jù)庫;然后使用MongoClient對象的connect()方法連接mongodb;最后通過node來對mongodb進行異步的增刪改查

  在mongodb數(shù)據(jù)庫中建立db1數(shù)據(jù)庫,然后通過以下代碼,建立col集合,并插入{"a":1}文檔

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongodb = require('mongodb');
mongodb.MongoClient.connect("mongodb://localhost/db1",function(err,db){    if(!err){
        db.collection("col").insert({"a":1},function(err,result){            if(!err){
                console.log(result);
            }
        })
    }
})

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

  最后返回結(jié)果如下

{ result: { ok: 1, n: 1 },
  ops: [ { a: 1, _id: 597077dc271d092728caa362 } ],
  insertedCount: 1,
  insertedIds: [ 597077dc271d092728caa362 ] }

 

概述

  Mongoose是NodeJS的驅(qū)動,不能作為其他語言的驅(qū)動。Mongoose有兩個特點

  1、通過關(guān)系型數(shù)據(jù)庫的思想來設計非關(guān)系型數(shù)據(jù)庫

  2、基于mongodb驅(qū)動,簡化操作

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

  Mongooose中,有三個比較重要的概念,分別是Schema、Model、Entity。它們的關(guān)系是:Schema生成Model,Model創(chuàng)造Document,Model和Document都可對數(shù)據(jù)庫操作造成影響,但Model比Document更具操作性

  Schema用于定義數(shù)據(jù)庫的結(jié)構(gòu)。類似創(chuàng)建表時的數(shù)據(jù)定義(不僅僅可以定義文檔的結(jié)構(gòu)和屬性,還可以定義文檔的實例方法、靜態(tài)模型方法、復合索引等),每個Schema會映射到mongodb中的一個collection,Schema不具備操作數(shù)據(jù)庫的能力

  Model是由Schema編譯而成的構(gòu)造器,具有抽象屬性和行為,可以對數(shù)據(jù)庫進行增刪查改。Model的每一個實例(instance)就是一個文檔document

  Document是由Model創(chuàng)建的實體,它的操作也會影響數(shù)據(jù)庫

 

安裝

  安裝nodejsmongodb之后 ,使用npm來安裝mongoose

npm install mongoose

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

  安裝成功后,就可以通過 require('mongoose') 來使用

 

連接數(shù)據(jù)庫

  使用require()方法在項目中包含mongoose后,接下來使用connect()方法連接到MongoDB數(shù)據(jù)庫

【connect()】

mongoose.connect(url);

  connect()最簡單的使用方式,就是只要傳入url參數(shù)即可,如下所示。連接到本地localhost的db1服務器

mongoose.connect('mongodb://localhost/db1');

  如果還需要傳遞用戶名、密碼,則可以使用如下方式

mongoose.connect('mongodb://username:password@host:port/database?options...');

  connect()方法還接受一個選項對象options,該對象將傳遞給底層驅(qū)動程序。這里所包含的所有選項優(yōu)先于連接字符串中傳遞的選項

mongoose.connect(uri, options);

  可用選項如下所示

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 db            -數(shù)據(jù)庫設置
 server        -服務器設置
 replset       -副本集設置
 user          -用戶名
 pass          -密碼
 auth          -鑒權(quán)選項
 mongos        -連接多個數(shù)據(jù)庫
 promiseLibrary

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var options = {
  db: { native_parser: true },
  server: { poolSize: 5 },
  replset: { rs_name: 'myReplicaSetName' },
  user: 'myUserName',
  pass: 'myPassword'}
mongoose.connect(uri, options);

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

  如果要連接多個數(shù)據(jù)庫,只需要設置多個url以,隔開,同時設置mongos為true

mongoose.connect('urlA,urlB,...', {
   mongos : true })

  connect()函數(shù)還接受一個回調(diào)參數(shù)

mongoose.connect(uri, options, function(error) {});

   執(zhí)行下列代碼后,控制臺輸出“連接成功”

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/test", function(err) {    if(err){
        console.log('連接失敗');
    }else{
        console.log('連接成功');
    }
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

   如果開啟鑒權(quán)控制,以用戶名"u1",密碼"123456"登錄'db1'數(shù)據(jù)庫。執(zhí)行代碼后,控制臺輸出“連接成功”

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(err){
        console.log('連接失敗');
    }else{
        console.log('連接成功');
    }
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

【disconnect()】 

mongoose.disconnect()

   使用disconnect()方法可以斷開連接

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(err){
        console.log('連接失敗');
    }else{
        console.log('連接成功');
    }
});
setTimeout(function(){
    mongoose.disconnect(function(){
        console.log("斷開連接");
    })
}, 2000);

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 

Schema

  Schema主要用于定義MongoDB中集合Collection里文檔document的結(jié)構(gòu)  

  定義Schema非常簡單,指定字段名和類型即可,支持的類型包括以下8種

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

String      字符串
Number      數(shù)字    
Date        日期
Buffer      二進制
Boolean     布爾值
Mixed       混合類型
ObjectId    對象ID    
Array       數(shù)組

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

  通過mongoose.Schema來調(diào)用Schema,然后使用new方法來創(chuàng)建schema對象

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');var Schema = mongoose.Schema;var mySchema = 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
  }
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

  [注意]創(chuàng)建Schema對象時,聲明字段類型有兩種方法,一種是首字母大寫的字段類型,另一種是引號包含的小寫字段類型

var mySchema = new Schema({title:String, author:String});//或者 var mySchema = new Schema({title:'string', author:'string'});

  如果需要在Schema定義后添加其他字段,可以使用add()方法

var MySchema = new Schema;
MySchema.add({ name: 'string', color: 'string', price: 'number' });

  

Model

  模型Model是根據(jù)Schema編譯出的構(gòu)造器,或者稱為類,通過Model可以實例化出文檔對象document

  文檔document的創(chuàng)建和檢索都需要通過模型Model來處理

【model()】

mongoose.model()

  使用model()方法,將Schema編譯為Model。model()方法的第一個參數(shù)是模型名稱

  [注意]一定要將model()方法的第一個參數(shù)和其返回值設置為相同的值,否則會出現(xiàn)不可預知的結(jié)果

  Mongoose會將集合名稱設置為模型名稱的小寫版。如果名稱的最后一個字符是字母,則會變成復數(shù);如果名稱的最后一個字符是數(shù)字,則不變;如果模型名稱為"MyModel",則集合名稱為"mymodels";如果模型名稱為"Model1",則集合名稱為"model1"

var schema = new mongoose.Schema({ num:Number, name: String, size: String});var MyModel = mongoose.model('MyModel', schema);

【實例化文檔document】

  通過對原型Model1使用new方法,實例化出文檔document對象

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(err){
        console.log('連接失敗');
    }else{
        console.log('連接成功');        var schema = new mongoose.Schema({ num:Number, name: String, size: String});        var MyModel = mongoose.model('MyModel', schema);        var doc1 = new MyModel({ size: 'small' });
        console.log(doc1.size);//'small'    }
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

【文檔保存】

  通過new Model1()創(chuàng)建的文檔doc1,必須通過save()方法,才能將創(chuàng)建的文檔保存到數(shù)據(jù)庫的集合中,集合名稱為模型名稱的小寫復數(shù)版

  回調(diào)函數(shù)是可選項,第一個參數(shù)為err,第二個參數(shù)為保存的文檔對象

save(function (err, doc) {})

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(!err){        var schema = new mongoose.Schema({ num:Number, name: String, size: String });        var MyModel = mongoose.model('MyModel', schema);        var doc1 = new MyModel({ size: 'small' });
        doc1.save(function (err,doc) {        //{ __v: 0, size: 'small', _id: 5970daba61162662b45a24a1 }          console.log(doc);
        })
    }
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

  由下圖所示,db1數(shù)據(jù)庫中的集合名稱為mymodels,里面有一個{size:"small"}的文檔

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 

自定義方法

【實例方法】

  Model的實例是document,內(nèi)置實例方法有很多,如 save,可以通過Schema對象的methods屬性給實例自定義擴展方法

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(!err){        var schema = new mongoose.Schema({ num:Number, name: String, size: String });        
        schema.methods.findSimilarSizes = function(cb){            return this.model('MyModel').find({size:this.size},cb);
        }        var MyModel = mongoose.model('MyModel', schema);        var doc1 = new MyModel({ name:'doc1', size: 'small' });        var doc2 = new MyModel({ name:'doc2', size: 'small' });        var doc3 = new MyModel({ name:'doc3', size: 'big' });
        doc1.save();
        doc2.save();
        doc3.save();
        setTimeout(function(){
            doc1.findSimilarSizes(function(err,docs){
                docs.forEach(function(item,index,arr){                    //doc1
                    //doc2                     console.log(item.name)        
                })
            })  
        },0)  
    }
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

【靜態(tài)方法】

  通過Schema對象的statics屬性給 Model 添加靜態(tài)方法

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(!err){        var schema = new mongoose.Schema({ num:Number, name: String, size: String });        
        schema.statics.findByName = function(name,cb){            return this.find({name: new RegExp(name,'i')},cb);
        }        var MyModel = mongoose.model('MyModel', schema);        var doc1 = new MyModel({ name:'doc1', size: 'small' });        var doc2 = new MyModel({ name:'doc2', size: 'small' });        var doc3 = new MyModel({ name:'doc3', size: 'big' });
        doc1.save();
        doc2.save();
        doc3.save();
        setTimeout(function(){
            MyModel.findByName('doc1',function(err,docs){                //[ { _id: 5971e68f4f4216605880dca2,name: 'doc1',size: 'small',__v: 0 } ]                console.log(docs);
            })  
        },0)  
    }
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

  由上所示,實例方法和靜態(tài)方法的區(qū)別在于,靜態(tài)方法是通過Schema對象的statics屬性model添加方法,實例方法是通過Schema對象的methods是給document添加方法

【查詢方法】

  通過schema對象的query屬性,給model添加查詢方法

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(!err){        var schema = new mongoose.Schema({ age:Number, name: String});        
        schema.query.byName = function(name){            return this.find({name: new RegExp(name)});
        }        var temp = mongoose.model('temp', schema);   
        temp.find().byName('huo').exec(function(err,docs){            //[ { _id: 5971f93be6f98ec60e3dc86c, name: 'huochai', age: 27 },
            // { _id: 5971f93be6f98ec60e3dc86e, name: 'huo', age: 30 } ]            console.log(docs);
        })  

    }           
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 

文檔新增

  文檔新增有三種方法,一種是使用上面介紹過的文檔的save()方法,另一種是使用模型model的create()方法,最后一種是模型model的insertMany()方法

【save()】

  [注意]回調(diào)函數(shù)可以省略

save([options], [options.safe], [options.validateBeforeSave], [fn])

  新建{age:10,name:'save'}文檔,并保存

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(!err){        var schema = new mongoose.Schema({ age:Number, name: String});        
        var temp = mongoose.model('temp', schema);        //使用鏈式寫法    
        new temp({age:10,name:'save'}).save(function(err,doc){            //[ { _id: 59720bc0d2b1125cbcd60b3f, age: 10, name: 'save', __v: 0 } ]            console.log(doc);        
        });         
    }           
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

【create()】

  使用save()方法,需要先實例化為文檔,再使用save()方法保存文檔。而create()方法,則直接在模型Model上操作,并且可以同時新增多個文檔

Model.create(doc(s), [callback])

  新增{name:"xiaowang"},{name:"xiaoli"}這兩個文檔

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {    if(!err){        var schema = new mongoose.Schema({ age:Number, name: String});        
        var temp = mongoose.model('temp', schema);   
        temp.create({name:"xiaowang"},{name:"xiaoli"},function(err,doc1,doc2){            //{ __v: 0, name: 'xiaowang', _id: 59720d83ad8a953f5cd04664 }            console.log(doc1); 
            //{ __v: 0, name: 'xiaoli', _id: 59720d83ad8a953f5cd04665 }            console.log(doc2); 
        });       
    }           
});

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓http://www.cnblogs.com/xiaohuochai/p/7215067.html