Mongoose使用——nodejs結合mongodb

 0. 前言:

Mongoose是NodeJS的驅動,不能做爲其餘語言的驅動。Mongoose有兩個特色:html

  • 經過關係型數據庫的思想來設計非關係型數據庫
  • 基於mongodb驅動,簡化操做

  Mongooose中,有三個比較重要的概念,分別是Schema、Model、Document。它們的關係是:Schema生成Model,Model創造Document,Model和Document均可對數據庫操做形成影響,但Model比Document更具操做性。html5

  Schema用於定義數據庫的結構。相似建立表時的數據定義(不只僅能夠定義文檔的結構和屬性,還能夠定義文檔的實例方法、靜態模型方法、複合索引等),每一個Schema會映射到mongodb中的一個collection,Schema不具有操做數據庫的能力。node

  Model是由Schema編譯而成的構造器,具備抽象屬性和行爲,能夠對數據庫進行增刪查改。Model的每個實例(instance)就是一個文檔document。git

  Document是由Model建立的實體,它的操做也會影響數據庫。github

1. 安裝

在此以前須要安裝nodejs和mongodb,才能使用npm來安裝mongoosemongodb

npm install mongoose

項目中可以使用下面的命令安裝mongoose並自動將其添加到依賴數據庫

npm i mongoose --save

2. 鏈接數據庫

2.1 首先使用 require() 引入mongoose

var mongoose = require('mongoose');

2.2 使用 connect() 來鏈接mongodb數據庫

mongoose.connect(url);

connect()最簡單的使用方式,就是隻要傳入url參數便可,以下所示。npm

/*直接鏈接*/
mongoose.connect("mongodb://127.0.0.1/mongoose_test" );
/*傳遞用戶名密碼來鏈接*/
mongoose.connect('mongodb://username:password@host:port/database?options...');

注意:mongoose版本大於或等於4.11.0時,鏈接數據庫會提示warning(不影響運行),避免的方法添加userMongoClient的設置,且屬性值爲trueapi

mongoose.connect('mongodb://數據庫的ip地址:端口號/數據庫名', { useMongoClient: true});

connect()方法還接受一個選項對象options,該對象將傳遞給底層驅動程序。數組

mongoose.connect(uri, options);

可用選項以下所示,更多詳見參考,options 所包含的全部選項優先於鏈接字符串中傳遞的選項

 db            -數據庫設置
 server        -服務器設置
 replset       -副本集設置
 user          -用戶名
 pass          -密碼
 auth          -鑑權選項
 mongos        -鏈接多個數據庫

若是要鏈接多個數據庫,只須要設置多個url以,隔開,同時設置mongos爲true

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

connect()函數還接受一個回調參數,來判斷是否鏈接成功

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

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

2.3 使用 disconnect() 斷開數據庫鏈接(通常不須要調用)

MongoDB數據庫,通常狀況下,只須要鏈接一次,鏈接一次之後,除非項目中止服務器關閉,不然鏈接通常不會斷開

mongoose.disconnect();

2.4 監聽MongoDB數據庫的鏈接狀態

在mongoose對象中,有一個屬性叫作connection,該對象表示的就是數據庫鏈接。經過監視該對象的狀態,能夠來監聽數據庫的鏈接與斷開

數據庫鏈接成功的事件

mongoose.connection.once("open",function(){});

數據庫斷開的事件

mongoose.connection.once("close",function(){});

3. Schema

Schema主要用於定義MongoDB中集合Collection裏文檔document的結構。  

定義Schema須要指定字段名和類型,支持的類型包括如下9種

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

經過mongoose.Schema來調用Schema,而後使用new方法來建立schema對象

var mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1/mongoose_test",{useMongoClient:true});
mongoose.connection.once("open",function () {
    console.log("數據庫鏈接成功~~~");
});

//將mongoose.Schema 賦值給一個變量
var Schema = mongoose.Schema;

//建立Schema(模式)對象
var stuSchema = new Schema({
    name:String,
    age:Number,
    gender:{
        type:String,
        default:"female"
    },
    address:String
});

[注意]建立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' });

4. Model & Document

模型Model是根據Schema編譯出的構造器,或者稱爲類,經過Model能夠實例化出文檔對象document。文檔document的建立和檢索都須要經過模型Model來處理

mongoose.model();

[注意]必定要將model()方法的第一個參數和其返回值設置爲相同的值,不然會出現不可預知的結果

  Mongoose會將集合名稱設置爲模型名稱的小寫版。若是名稱的最後一個字符是字母,則會變成複數;若是名稱的最後一個字符是數字,則不變;若是模型名稱爲"MyModel",則集合名稱爲"mymodels";若是模型名稱爲"Model1",則集合名稱爲"model1"。

實例化文檔document

var StuModel = mongoose.model("student" , stuSchema);
//Document 和 集合中的文檔一一對應 , Document是Model的實例  經過Model查詢到結果都是Document
//建立一個Document
var stu = new StuModel({
    name:"孫悟空",
    age:18,
    gender:"male",
    address:"花果山"
});

文檔保存

經過new StuModel()建立的文檔stu,必須經過save()方法,才能將建立的文檔保存到數據庫的集合中,集合名稱爲模型名稱的小寫複數版

//回調函數是可選項,第一個參數爲err,第二個參數爲保存的文檔對象
save(function (err, doc) {})
stu.save(function (err) {
  if (err) return handleError(err);
})

也可減小步驟,直接向數據庫插入文檔

var StuModel = mongoose.model("student" , stuSchema);

//向數據庫中插入一個文檔
//StuModel.create(doc, function(err){});
StuModel.create({
    name:"白骨精",
    age:16,
    address:"白骨洞"
},function (err) {
    if(!err){
        console.log("插入成功~~~");
    }
});

結果

  

5. Model對象的方法

    

有了Model,咱們就能夠來對數據庫進行增刪改查的操做了。具體方法可參考官方文檔

5.1 增長方法

Model.create(doc(s), [callback])
     - 用來建立一個或多個文檔並添加到數據庫中
     - 參數:
         doc(s) 能夠是一個文檔對象,也能夠是一個文檔對象的數組
         callback 當操做完成之後調用的回調函數
StuModel.create([
    {
        name:"沙和尚",
        age:38,
        gender:"male",
        address:"流沙河"
    }

],function (err) {
    if(!err){
        console.log(arguments);
    }
});

控制檯輸出

5.2 修改方法

 Model.update(conditions, doc, [options], [callback])
 Model.updateMany(conditions, doc, [options], [callback])
 Model.updateOne(conditions, doc, [options], [callback])
     - 用來修改一個或多個文檔
     - 參數:
         conditions 查詢條件
         doc 修改後的對象
         options 配置參數
         callback 回調函數
 Model.replaceOne(conditions, doc, [options], [callback])
StuModel.updateOne({name:"唐僧"},{$set:{age:20}},function (err) {
    if(!err){
        console.log("修改爲功");
    }
});

 5.3 查詢方法

Model.find(conditions, [projection], [options], [callback])
      - 查詢全部符合條件的文檔 總會返回一個數組
Model.findById(id, [projection], [options], [callback])
      - 根據文檔的id屬性查詢文檔
Model.findOne([conditions], [projection], [options], [callback])
      - 查詢符合條件的第一個文檔 總會返回一個具體的文檔對象(非數組)

         conditions 查詢的條件
         projection 投影 須要獲取到的字段
             - 兩種方式
                 {name:1,_id:0}
                 "name -_id"
         options  查詢選項(skip limit)
                 {skip:3 , limit:1}
         callback 回調函數,查詢結果會經過回調函數返回
                     回調函數必須傳,若是不傳回調函數,壓根不會查詢

官方文檔查詢方法截圖以下

下面分別演示幾種不一樣的查詢方法

//查詢name爲「唐僧」的
StuModel.find({name:"唐僧"},function (err , docs) {
    if(!err){
        console.log(docs);
    }
});

結果

//只查詢name,且不查詢_id  (_id字段默認輸出)
StuModel.find({},{name:1 , _id:0},function (err , docs) {
    if(!err){
        console.log(docs);
    }
});

結果

//只查詢文檔的name,age值,查詢時跳過3個,結果集限制只查詢出一個
StuModel.find({},"name age -_id", {skip:3 , limit:1} , function (err , docs) {
    if(!err){
        console.log(docs);
    }
});

結果

StuModel.findOne({} , function (err , doc) {
    if(!err){
        console.log(doc);
    }
});

結果

StuModel.findById("59c4c3cf4e5483191467d392" , function (err , doc) {
    if(!err){
        //console.log(doc);
        //經過find()查詢的結果,返回的對象,就是Document,文檔對象
        //Document對象是Model的實例
        console.log(doc instanceof StuModel);
    }
});

結果

5.4 刪除方法

 Model.remove(conditions, [callback])
 Model.deleteOne(conditions, [callback])
 Model.deleteMany(conditions, [callback])
StuModel.remove({name:"白骨精"},function (err) {
    if(!err){
        console.log("刪除成功~~");
    }
});

5.5 統計

 Model.count(conditions, [callback])
     - 統計文檔的數量的
StuModel.count({},function (err , count) {
    if(!err){
        console.log(count);
    }
});

 6. Document對象的方法

Document 和 集合中的文檔一一對應,Document是Model的實例。經過Model查詢到結果都是Document。

  

6.1 保存

save([options], [options.safe], [options.validateBeforeSave], [fn])
//建立一個Document
var stu = new StuModel({
    name:"奔波霸",
    age:48,
    gender:"male",
    address:"碧波潭"
});
//保存改document對象
stu.save(function (err,product,numAffected) { //返回三個對象 err:失敗信息; product:保存的對象; numAffected:該document對象被持久化了爲1,不然爲0
if(!err){ 
    console.log("保存成功~~~");
}

6.2 更新

update(update,[options],[callback])
doc.update({$set:{age:28}},function (err) {
            if(!err){
                console.log("修改爲功~~~");
            }
});

或者對document對象進行修改,再執行save()方法

doc.age = 28;
doc.save();

6.3 刪除

remove([callback])
doc.remove(function (err) {
            if(!err){
                console.log("刪除成功~~~");
            }
  });

6.4 其餘

get(name)
     - 獲取文檔中的指定屬性值
set(name , value)
     - 設置文檔的指定的屬性值
id
     - 獲取文檔的_id屬性值
toJSON() ******
     - 轉換爲一個JSON對象
toObject()
     - 將Document對象轉換爲一個普通的JS對象【轉換爲普通的js對象之後,注意全部的Document對象的方法或屬性都不能使用了】
console.log(doc.get("age"));
console.log(doc.age);

doc.set("name","豬九戒");
doc.name = "hahaha";

console.log(doc._id);
var j = doc.toJSON();
console.log(j);

var o = doc.toObject();
console.log(o);

doc = doc.toObject();
delete doc.address;

console.log(doc._id);

 

參考:

官方文檔

Mongoose基礎入門

尚硅谷培訓課程

相關文章
相關標籤/搜索