mongoose mongoDB 數據庫的增刪改查 CRUD

# Mongoose
## 簡介
- Mongoose 是MongoDB的一個對象模型工具,是 nodejs 操作 MongoDB 的第三方框架,可以在異步的環境下執行。
- 同時它也是針對MongoDB操作的一個對象模型庫,封裝了MongoDB對文檔的的一些增刪改查等常用方法,讓NodeJS操作Mongodb數據庫變得更加靈活簡單。

        - 參考資料
            - 文檔: www.mongoosejs.com
            - mongoose 的 API 是我見過的最好的文檔,沒有之一 
                - 雖然只有英文版,但是,光看例子也能夠理解基本含義

##安裝引用
- 安裝mongoose:
        npm install mongoose
- 引用mongoose:
        var mongoose = require("mongoose");
- 使用"mongoose"連接數據庫:
        mongoose.connect("mongodb://user:pass@localhost:port/database");
- 錯誤檢查
    ```    
        var connection = mongoose.connection;
        connection.on('error', function(err){
            console.error(err);
        });
        connection.on('open', function() {
            // we're connected!
            console.log('we are connected!');
        });
    ```

## Mongoose 最重要(最難)的三個概念
1. Schema : 模式,規範
2. Model : 模型,函數
3. Entity : 實體,實例,對象

三者之間的關係
![三者關係示意圖](./mongoose 設計思路示意圖.jpg)


### Schema 簡述
- 含義: Schema —— 一種以文件形式存儲的數據庫模型骨架,可以說是數據屬性模型【傳統意義的表結構】,又或着是“集合”的模型骨架。 Schema 無法直接連接數據庫端,也就是說它不具備對數據庫的操作能力,僅僅只是數據模型在程序片段中的一種表現。說白了就是規定了一種數據存儲格式
- 代碼定義        
        var mongoose = require("mongoose");
        var MonsterSchema = new mongoose.Schema({
            name : { type:String },    //屬性name,類型爲String
            age  : { type:Number, default:0 },    //屬性age,類型爲Number,默認爲0
            time : { type:Date, default:Date.now },
            email: { type:String,default:''}
        });
        //基本屬性類型有:字符串、日期型、數值型、布爾型(Boolean)、null、數組、內嵌文檔等。

### Model 簡述
- 含義: Model —— 由Schema構造生成的模型,它具有了Schema定義的數據庫骨架(數據格式數據模型)。此外,更重要的是還具有數據庫操作的行爲,類似於管理數據庫屬性、行爲的類。
- 創建一個 Model 模型,我們需要指定:
    1. 集合名稱
    2. 集合的 Schema 結構對象
- 代碼        
        // 創建Model
        var MonsterModel = mongoose.model("Monster", MonsterSchema);
        // MonsterModel:數據庫中的集合名稱,當我們對其添加數據時如果 MonsterModel 已經存在,則會保存到其目錄下,如果未存在,則會創建 MonsterModel 集合,然後在保存數據。

擁有了Model,我們也就擁有了操作數據庫的法寶,在後面的課程中,我們就會學習使用Model來進行增刪改查的具體操作
如果需要對某個集合有所作爲,那就交給 Model 模型來處理。

### Entity 簡述
- 含義 Entity —— 由 Model 創建的實體,Entity 指代某一條具體的文檔,model 指代某個表(collection)。 Model 和 Entity 都能操作數據庫,但 Model 比 Entity 具有更大的操作空間
- 代碼
        // 使用Model創建Entity
        var monsterEntity = new MonsterModel({    
               name : "niuMoWang",
               age  : 2000,
               email: "[email protected]"
        });
        //說白了,就是 new 了一個對象
        console.log(niuMoWang.name); 
        console.log(niuMoWang.age); 
        //創建成功之後,Schema 屬性就變成了 Model 和 Entity 的公共屬性了

##**增刪改查**
###增
- Model 保存方法
    - 方法:Model.create(文檔數據, callback))
    - 代碼:
            MonsterModel.create({ name:"路人甲", age:2}, function(error, doc){
                if(error) {
                    console.log(error);
                } else {
                    console.log(doc);
                }
            });
- Entity 保存方法
    - 方法:Entity.save( callback ))
    - 代碼:
            var entity = new MonsterModel({ name:"路人甲", age:2});
            entity.save(function(error,doc) {
                if(error) {
                    console.log(error);
                } else {
                    console.log(doc);
                }
            });

###刪
- Model 刪除方法
    - 方法:model.remove(查詢條件,callback);
    - 代碼:
            var conditions = { name: '路人甲' };
            MonsterModel.remove(conditions, function(error){
                if(error) {
                    console.log(error);
                } else {
                    console.log('Delete success!');
                }
            });
- Entity 刪除方法
    - 方法:obj.remove(callback);
    - 代碼:
            entity.remove(function(err, doc){
                if(err){
                    console.error(err);
                } else {
                    console.log(doc);
                }
            });
            
###改
- Model 更新方法
    - 方法:obj.update(查詢條件, 更新對象, callback);
    - 代碼:
            ar conditions = {name : '路人甲'};        
            var update = {$set : { age : 3 }};        
            MonsterModel.update(conditions, update, function(error){
                if(error) {
                    console.log(error);
                } else {
                    console.log('Update success!');
                }
            });
- Entity 更新方法
    - 方法:obj.save(callback);
    - 代碼:
            entity.age = 3;
            entity.save(function(err, doc){
                if(err){
                    console.error(err);
                } else {
                    console.log(doc);
                }
            });

###查
- **find查詢**【最重要】
    - 方法: obj.find(查詢條件, 過濾條件, callback);
    - 代碼:
            MonsterModel.find({},function(error,docs){
               //若沒有向find傳遞參數,默認的是顯示所有文檔
            });        
            MonsterModel.find({ "age": 3 }, {_id:0}, function (error, docs) {
              if(error){
                console.log("error :" + error);
              }else{
                console.log(docs); //docs: age爲28的所有文檔
              }
            }); 
    - 備註:
        - 查詢條件有很多種,上面這段代碼,代換不同的查詢條件有不一樣的效果
        - 過濾條件控制那些屬性最終會包含在結果集當中,如果過濾條件省略或爲Null,則返回所有屬性。
- 單條數據查詢
    - 方法: findOne(Conditions,callback);
    - 代碼:
            MonsterModel.findOne({ age: 3}, function (err, doc){
               // 查詢符合age等於27的第一條數據
               // doc是查詢結果
            });
            // findOne方法,只返回第一個符合條件的文檔數據。
    - 方法:findById(_id, callback);
    - 代碼:
            MonsterModel.findById('obj._id', function (err, doc){
             //doc 查詢結果文檔
            });   

####查詢條件
"$lt"(小於),"$lte"(小於等於),"$gt"(大於),"$gte"(大於等於),"$ne"(不等於),"$in"(可單值和多個值的匹配),"$or"(查詢多個鍵值的任意給定值),"$exists"(表示是否存在的意思)。
- 大於、小於、不等於
        MonsterModel.find({"age":{"$gt":18}},function(error,docs){
           //查詢所有nage大於18的數據
        });        
        MonsterModel.find({"age":{"$lt":60}},function(error,docs){
           //查詢所有nage小於60的數據
        });        
        MonsterModel.find({"age":{"$gt":18,"$lt":60}},function(error,docs){
           //查詢所有nage大於18小於60的數據
        });
        MonsterModel.find({ age:{ $ne:24}},function(error,docs){
            //查詢age不等於24的所有數據
        });        
        MonsterModel.find({name:{$ne:"路人甲"},age:{$gte:3}},function(error,docs){
          //查詢name不等於tom、age>=18的所有數據
        });

- 包含
        MonsterModel.find({ age:{ $in: 2}},function(error,docs){
           //查詢age等於20的所有數據
        });        
        MonsterModel.find({ age:{$in:[2,3]}},function(error,docs){
          //可以把多個值組織成一個數組
        }); 

- 邏輯或    
        MonsterModel.find({"$or":[{"name":"yellowBrow"},{"age":500}]},function(error,docs){
          //查詢name爲yaya或age爲28的全部文檔
        });

- 屬性是否存在
        MonsterModel.find({name: {$exists: true}},function(error,docs){
          //查詢所有存在name屬性的文檔
        });
        MonsterModel.find({telephone: {$exists: false}},function(error,docs){
          //查詢所有不存在telephone屬性的文檔
        });

##遊標
數據庫使用遊標返回 find 的執行結果。
客戶端對遊標的實現通常能夠對最終結果進行有效的控制。可以限制結果的數量,略過部分結果,根據任意鍵按任意順序的組合對結果進行各種排序。
最常用的查詢選項就是限制返回結果的數量(limit函數)、忽略一點數量的結果(skip函數)以及排序(sort函數)。所有這些選項一點要在查詢被髮送到服務器之前指定。
###遊標的三大函數
 sort函數 --------  skip函數  --------  limit函數
1. ** sort 函數  **
    - 介紹:sort函數可以將查詢結果數據進行排序操作,該函數的參數是一個或多個鍵/值對,鍵代表要排序的鍵名,值代表排序的方向,1是升序,-1是降序。
    - 方法:find(Conditions,fields,options,callback);
    - 代碼:
            Model.find({},null,{sort:{age:-1}},function(err,docs){
                  //查詢所有數據,並按照age降序順序返回數據docs
            });

2. **  skip 函數  **
    - 介紹:跳過指定數量的匹配結果,返回餘下的查詢結果。
    - 方法:find(Conditions,fields,options,callback);
    - 代碼;
            Model.find({},null,{skip:4},function(err,docs){
                console.log(docs);
            });
            // 如果查詢結果數量中少於4個的話,則不會返回任何結果。

3. ** limit 函數 **
    - 介紹:在查詢操作中,有時數據量會很大,這時我們就需要對返回結果的數量進行限制,那麼我們就可以使用limit函數,通過它來限制結果數量。
    - 方法:find(Conditions,fields,options,callback);
    - 代碼:
            Model.find({},null,{limit:20},function(err,docs){
                console.log(docs);    
            });
            // 如果匹配的結果不到20個,則返回匹配數量的結果,也就是說limit函數指定的是上限而非下限。



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章