国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

一篇文章帶你入門Mongoose

wayneli / 1328人閱讀

摘要:當(dāng)然,可以使用方法來簡寫代碼刪除第個(gè)元素類似的,該方法也不能省略回調(diào)函數(shù),否則數(shù)據(jù)不會(huì)被刪除。

走在前端的大道上

Mongoose是在node.js環(huán)境下對(duì)mongodb進(jìn)行便捷操作的對(duì)象模型工具

因此,要使用mongoose,則必須安裝node.js環(huán)境以及mongodb數(shù)據(jù)庫。mongoose使mongodb操作更簡單便捷。可以在 github 中獲得其源碼,也可以在這里查看 api 文檔,英文的。

安裝

  
安裝nodejs和mongodb之后 ,使用npm來安裝mongoose

npm install mongoose --save

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


connect connect 用于創(chuàng)建數(shù)據(jù)庫連接
mongoose.connect(url(s), [options], [callback])
//url(s):數(shù)據(jù)庫地址,可以是多個(gè),以`,`隔開
//options:可選,配置參數(shù)
//callback:可選,回調(diào)
mongoose.connect("mongodb://數(shù)據(jù)庫地址(包括端口號(hào))/數(shù)據(jù)庫名稱")
指定用戶連接
mongoose.connect("mongodb://用戶名:密碼@127.0.0.1:27017/數(shù)據(jù)庫名稱")
連接多個(gè)數(shù)據(jù)庫

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

mongoose.connect("urlA,urlB,...", {
   mongos : true 
})
回調(diào)參數(shù)
mongoose.connect(url, options, function(error) {

});

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

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

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

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

簡單實(shí)驗(yàn)

創(chuàng)建一個(gè)db.js

var mongoose = require("mongoose"),
    DB_URL = "mongodb://localhost:27017/mongoosesample";

/**
 * 連接
 */
mongoose.connect(DB_URL);

/**
  * 連接成功
  */
mongoose.connection.on("connected", function () {    
    console.log("Mongoose connection open to " + DB_URL);  
});    

/**
 * 連接異常
 */
mongoose.connection.on("error",function (err) {    
    console.log("Mongoose connection error: " + err);  
});    
 
/**
 * 連接斷開
 */
mongoose.connection.on("disconnected", function () {    
    console.log("Mongoose connection disconnected");  
});    

  調(diào)用node db.js執(zhí)行就會(huì)看到輸出如下圖


disconnect()
mongoose.disconnect()

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

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


Schema

Schema主要用于定義MongoDB中集合Collection里文檔document的結(jié)構(gòu),可以理解為mongoose對(duì)表結(jié)構(gòu)的定義(不僅僅可以定義文檔的結(jié)構(gòu)和屬性,還可以定義文檔的實(shí)例方法、靜態(tài)模型方法、復(fù)合索引等),每個(gè)schema會(huì)映射到mongodb中的一個(gè)collection,schema不具備操作數(shù)據(jù)庫的能力

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

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

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

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

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

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是由Schema編譯而成的假想(fancy)構(gòu)造器,具有抽象屬性和行為。Model的每一個(gè)實(shí)例(instance)就是一個(gè)document,document可以保存到數(shù)據(jù)庫和對(duì)數(shù)據(jù)庫進(jìn)行操作。簡單說就是model是由schema生成的模型,可以對(duì)數(shù)據(jù)庫的操作。

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

mongoose.model(`文檔名稱`, Schema)

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

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

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

【實(shí)例化文檔document】

  通過對(duì)原型Model1使用new方法,實(shí)例化出文檔document對(duì)象

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

【文檔保存】

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

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

save(function (err, doc) {})
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);
        })
    }
});

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

自定義方法
【實(shí)例方法】

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

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

【靜態(tài)方法】

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

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

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

【Methods 和 Statics 的區(qū)別】

statics是給model添加方法,methods是給實(shí)例(instance)添加方法。methods和statics的區(qū)別

//module.exports = mongoose.model(`Article`, ArticleSchema )
//將article的model保存為文件 article.js

const Article = require("../models/article")

// statics
Article.staticFunc ()

//methods
const article = new Article(arguments)
article.methodFunc()

【查詢方法】

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

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

    }           
});

文檔新增

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

save()

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

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

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

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);
        //使用鏈?zhǔn)綄懛?   
        new temp({age:10,name:"save"}).save(function(err,doc){
            //[ { _id: 59720bc0d2b1125cbcd60b3f, age: 10, name: "save", __v: 0 } ]
            console.log(doc);        
        });         
    }           
});
create()

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

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

  新增{name:"xiaowang"},{name:"xiaoli"}這兩個(gè)文檔

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

Model.insertMany(doc(s), [options], [callback])
  新增{name:"a"},{name:"b"}這兩個(gè)文檔

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.insertMany([{name:"a"},{name:"b"}],function(err,docs){
            //[ { __v: 0, name: "a", _id: 59720ea1bbf5792af824b30c },
            //{ __v: 0, name: "b", _id: 59720ea1bbf5792af824b30d } ]
            console.log(docs); 
        });       

    }           
});

文檔查詢

使用Mongoose來查找文檔很容易,有以下3種方法可供選擇

find()
findById()
findOne()
find()

  第一個(gè)參數(shù)表示查詢條件,第二個(gè)參數(shù)用于控制返回的字段,第三個(gè)參數(shù)用于配置查詢參數(shù),第四個(gè)參數(shù)是回調(diào)函數(shù),回調(diào)函數(shù)的形式為function(err,docs){}

Model.find(conditions, [projection], [options], [callback])

  在數(shù)據(jù)庫db1的集合temps中存在如下數(shù)據(jù)

 現(xiàn)在,使用find()方法找出所有數(shù)據(jù)

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.find(function(err,docs){
            //[ { _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 27 },
            //{ _id: 5971f93be6f98ec60e3dc86d, name: "wang", age: 18 },
            //{ _id: 5971f93be6f98ec60e3dc86e, name: "huo", age: 30 },
            //{ _id: 5971f93be6f98ec60e3dc86f, name: "li", age: 12 } ]
            console.log(docs);
        })
    }
});
找出年齡大于18的數(shù)據(jù)
   temp.find({age:{$gte:18}},function(err,docs){
        //[ { _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 27 },
        //{ _id: 5971f93be6f98ec60e3dc86d, name: "wang", age: 18 },
        //{ _id: 5971f93be6f98ec60e3dc86e, name: "huo", age: 30 }]
        console.log(docs);
    })

  找出年齡大于18且名字里存在"huo"的數(shù)據(jù)

 temp.find({name:/huo/,age:{$gte:18}},function(err,docs){
            //[ { _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 27 },
            //{ _id: 5971f93be6f98ec60e3dc86e, name: "huo", age: 30 }]
            console.log(docs);
        })

  找出名字里存在"a"的數(shù)據(jù),且只輸出"name"字段

  [注意]_id字段默認(rèn)輸出

 temp.find({name:/a/},"name",function(err,docs){
    //[ { _id: 5971f93be6f98ec60e3dc86c, name: "huochai" },
    //{ _id: 5971f93be6f98ec60e3dc86d, name: "wang" } ]
     console.log(docs);
  })

  如果確實(shí)不需要_id字段輸出,可以進(jìn)行如下設(shè)置

  temp.find({name:/a/},{name:1,_id:0},function(err,docs){
    //[ { name: "huochai" }, { name: "wang" } ]
     console.log(docs);
  })
找出跳過前兩條數(shù)據(jù)的其他所有數(shù)據(jù)

  [注意]如果使用第三個(gè)參數(shù),前兩個(gè)參數(shù)如果沒有值,需要設(shè)置為null

    temp.find(null,null,{skip:2},function(err,docs){
        //[ { _id: 5971f93be6f98ec60e3dc86e, name: "huo", age: 30 },
        //{ _id: 5971f93be6f98ec60e3dc86f, name: "li", age: 12 } ]
        console.log(docs);
    })
findById()
Model.findById(id, [projection], [options], [callback])

  顯示第0個(gè)元素的所有字段

    var aIDArr = [];
    temp.find(function(err,docs){
        docs.forEach(function(item,index,arr){
            aIDArr.push(item._id);
        })
        temp.findById(aIDArr[0],function(err,doc){
            //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 27 }
            console.log(doc);
        })            
    })

  以上代碼的另一種寫法如下

    var aIDArr = [];
    temp.find(function(err,docs){
        docs.forEach(function(item,index,arr){
            aIDArr.push(item._id);
        })
        temp.findById(aIDArr[0]).exec(function(err,doc){
            //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 27 }
            console.log(doc);
        })            
    })

  只輸出name字段

    temp.findById(aIDArr[0],{name:1,_id:0},function(err,doc){
        //{  name: "huochai"}
        console.log(doc);
    })

  或者寫成下面這種形式

    temp.findById(aIDArr[0],{name:1,_id:0}).exec(function(err,doc){
        //{  name: "huochai"}
        console.log(doc);
    })

  輸出最少的字段

    temp.findById(aIDArr[0],{lean:true},function(err,doc){
        //{ _id: 5971f93be6f98ec60e3dc86c }
        console.log(doc);
    })   
    temp.findById(aIDArr[0],{lean:true}).exec(function(err,doc){
        //{ _id: 5971f93be6f98ec60e3dc86c }
        console.log(doc);
    })     
findOne()

該方法返回查找到的所有實(shí)例的第一個(gè)

Model.findOne([conditions], [projection], [options], [callback])

  找出age>20的文檔中的第一個(gè)文檔

    temp.findOne({age:{$gt : 20}},function(err,doc){
        //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 27 }
        console.log(doc);
    })   
    temp.findOne({age:{$gt : 20}}).exec(function(err,doc){
        //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 27 }
        console.log(doc);
    }) 

 找出age>20的文檔中的第一個(gè)文檔,且只輸出name字段

temp.findOne({age:{$gt : 20}},{name:1,_id:0},function(err,doc){
    //{ name: "huochai" }
    console.log(doc);
})   
temp.findOne({age:{$gt : 20}},{name:1,_id:0}).exec(function(err,doc){
    //{ name: "huochai" }
    console.log(doc);
})     

  找出age>20的文檔中的第一個(gè)文檔,且輸出包含name字段在內(nèi)的最短字段

temp.findOne({age:{$gt : 20}},"name",{lean:true},function(err,doc){
    //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai" }
    console.log(doc);
})   
temp.findOne({age:{$gt : 20}},"name").lean().exec(function(err,doc){
    //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai" }
    console.log(doc);
})   

 文檔查詢中,常用的查詢條件如下

$or    或關(guān)系
$nor    或關(guān)系取反
$gt    大于
$gte    大于等于
$lt    小于
$lte    小于等于
$ne    不等于
$in    在多個(gè)值范圍內(nèi)
$nin    不在多個(gè)值范圍內(nèi)
$all    匹配數(shù)組中多個(gè)值
$regex   正則,用于模糊查詢
$size   匹配數(shù)組大小
$maxDistance 范圍查詢,距離(基于LBS)
$mod    取模運(yùn)算
$near    鄰域查詢,查詢附近的位置(基于LBS)
$exists   字段是否存在
$elemMatch 匹配內(nèi)數(shù)組內(nèi)的元素
$within   范圍查詢(基于LBS)
$box     范圍查詢,矩形范圍(基于LBS)
$center   范圍醒詢,圓形范圍(基于LBS)
$centerSphere 范圍查詢,球形范圍(基于LBS)
$slice    查詢字段集合中的元素(比如從第幾個(gè)之后,第N到第M個(gè)元素
$where

  如果要進(jìn)行更復(fù)雜的查詢,需要使用$where操作符,$where操作符功能強(qiáng)大而且靈活,它可以使用任意的JavaScript作為查詢的一部分,包含JavaScript表達(dá)式的字符串或者JavaScript函數(shù)

使用字符串

temp.find({$where:"this.x == this.y"},function(err,docs){

//[ { _id: 5972ed35e6f98ec60e3dc887,name: "wang",age: 18,x: 1,y: 1 },
//{ _id: 5972ed35e6f98ec60e3dc889, name: "li", age: 20, x: 2, y: 2 } ]
console.log(docs);

})
temp.find({$where:"obj.x == obj.y"},function(err,docs){

//[ { _id: 5972ed35e6f98ec60e3dc887,name: "wang",age: 18,x: 1,y: 1 },
//{ _id: 5972ed35e6f98ec60e3dc889, name: "li", age: 20, x: 2, y: 2 } ]
console.log(docs);

})

使用函數(shù)

temp.find({$where:function(){
        return obj.x !== obj.y;
    }},function(err,docs){
    //[ { _id: 5972ed35e6f98ec60e3dc886,name: "huochai",age: 27,x: 1,y: 2 },
    //{ _id: 5972ed35e6f98ec60e3dc888, name: "huo", age: 30, x: 2, y: 1 } ]
    console.log(docs);
}) 
temp.find({$where:function(){
        return this.x !== this.y;
    }},function(err,docs){
    //[ { _id: 5972ed35e6f98ec60e3dc886,name: "huochai",age: 27,x: 1,y: 2 },
    //{ _id: 5972ed35e6f98ec60e3dc888, name: "huo", age: 30, x: 2, y: 1 } ]
    console.log(docs);
}) 

文檔更新

文檔更新可以使用以下幾種方法

update()
updateMany()
find() + save()
updateOne()
findOne() + save()
findByIdAndUpdate()
fingOneAndUpdate()
update()

  第一個(gè)參數(shù)conditions為查詢條件,第二個(gè)參數(shù)doc為需要修改的數(shù)據(jù),第三個(gè)參數(shù)options為控制選項(xiàng),第四個(gè)參數(shù)是回調(diào)函數(shù)

Model.update(conditions, doc, [options], [callback])

  options有如下選項(xiàng)

   safe (boolean): 默認(rèn)為true。安全模式。
  upsert (boolean): 默認(rèn)為false。如果不存在則創(chuàng)建新記錄。
  multi (boolean): 默認(rèn)為false。是否更新多個(gè)查詢記錄。
  runValidators: 如果值為true,執(zhí)行Validation驗(yàn)證。
  setDefaultsOnInsert: 如果upsert選項(xiàng)為true,在新建時(shí)插入文檔定義的默認(rèn)值。
  strict (boolean): 以strict模式進(jìn)行更新。
  overwrite (boolean): 默認(rèn)為false。禁用update-only模式,允許覆蓋記錄。

  數(shù)據(jù)庫temps中現(xiàn)有數(shù)據(jù)如下

現(xiàn)在使用update()方法查詢age大于20的數(shù)據(jù),并將其年齡更改為40歲

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.update({age:{$gte:20}},{age:40},function(err,raw){
            //{ n: 1, nModified: 1, ok: 1 }
            console.log(raw);
        })

    }           
});

  經(jīng)過以上操作,數(shù)據(jù)庫結(jié)果如下。只有第一個(gè)數(shù)據(jù)更改為40歲。而第三個(gè)數(shù)據(jù)沒有發(fā)生變化

  如果要同時(shí)更新多個(gè)記錄,需要設(shè)置options里的multi為true。下面將名字中有"a"字符的年齡設(shè)置為10歲

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.update({name:/a/},{age: 10},{multi:true},function(err,raw){
            //{ n: 2, nModified: 2, ok: 1 }
            console.log(raw);
        })

    }           
});

如果設(shè)置的查找條件,數(shù)據(jù)庫里的數(shù)據(jù)并不滿足,默認(rèn)什么事都不發(fā)生

temp.update({age:100},{name: "hundred"},function(err,raw){
    //{ n: 0, nModified: 0, ok: 1 }
    console.log(raw);
})

  如果設(shè)置options里的upsert參數(shù)為true,若沒有符合查詢條件的文檔,mongo將會(huì)綜合第一第二個(gè)參數(shù)向集合插入一個(gè)新的文檔

temp.update({age:100},{name: "hundred"},{upsert:true},function(err,raw){
    //{ n: 1, nModified: 0,upserted: [ { index: 0, _id: 5972c202d46b621fca7fc8c7 } ], ok: 1 }
    console.log(raw);
})

temp.update({name:/aa/},{age: 0},{upsert:true},function(err,raw){
    //{ n: 1, nModified: 0,upserted: [ { index: 0, _id: 5972c288d46b621fca7fdd8f } ], ok: 1 }
    console.log(raw);
})

 [注意]update()方法中的回調(diào)函數(shù)不能省略,否則數(shù)據(jù)不會(huì)被更新。如果回調(diào)函數(shù)里并沒有什么有用的信息,則可以使用exec()簡化代碼

temp.update({name:/aa/},{age: 0},{upsert:true}).exec();
updateMany()

 updateMany()與update()方法唯一的區(qū)別就是默認(rèn)更新多個(gè)文檔,即使設(shè)置{multi:false}也無法只更新第一個(gè)文檔

Model.updateMany(conditions, doc, [options], [callback])

  將數(shù)據(jù)庫中名字中帶有"huo"的數(shù)據(jù),年齡變?yōu)?0歲

temp.updateMany({name:/huo/},{age:50},function(err,raw){
    //{ n: 2, nModified: 2, ok: 1 }
    console.log(raw);
});

find() + save()

如果需要更新的操作比較復(fù)雜,可以使用find()+save()方法來處理,比如找到年齡小于30歲的數(shù)據(jù),名字后面添加"30"字符

temp.find({age:{$lt:20}},function(err,docs){
    //[ { _id: 5971f93be6f98ec60e3dc86d, name: "wang", age: 10 },
    //{ _id: 5971f93be6f98ec60e3dc86f, name: "li", age: 12 }]
    console.log(docs);
    docs.forEach(function(item,index,arr){
        item.name += "30";
        item.save();
    })
    //[ { _id: 5971f93be6f98ec60e3dc86d, name: "wang30", age: 10 },
    // { _id: 5971f93be6f98ec60e3dc86f, name: "li30", age: 12 }]
    console.log(docs);
});
updateOne()

updateOne()方法只能更新找到的第一條數(shù)據(jù),即使設(shè)置{multi:true}也無法同時(shí)更新多個(gè)文檔

  將數(shù)據(jù)庫中名字中帶有"huo"的數(shù)據(jù),年齡變?yōu)?0歲

temp.updateOne({name:/huo/},{age:60},function(err,raw){
    //{ n: 1, nModified: 1, ok: 1 }
    console.log(raw);
});

findOne() + save()

  如果需要更新的操作比較復(fù)雜,可以使用findOne()+save()方法來處理,比如找到名字為"huochai"的數(shù)據(jù),年齡加100歲

temp.findOne({name:"huochai"},function(err,doc){
    //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 10 }
    console.log(doc);
    doc.age += 100;
    doc.save();
    //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 110 }
    console.log(doc);
});
findOneAndUpdate()

  fineOneAndUpdate()方法的第四個(gè)參數(shù)回調(diào)函數(shù)的形式如下function(err,doc){}

Model.findOneAndUpdate([conditions], [update], [options], [callback])
findByIdAndUpdate

   fineByIdAndUpdate()方法的第四個(gè)參數(shù)回調(diào)函數(shù)的形式如下function(err,doc){}

Model.findOneAndUpdate([conditions], [update], [options], [callback])

文檔刪除

  有三種方法用于文檔刪除

remove()
findOneAndRemove()
findByIdAndRemove()
remove()

  remove有兩種形式,一種是文檔的remove()方法,一種是Model的remove()方法

  下面介紹Model的remove()方法,該方法的第一個(gè)參數(shù)conditions為查詢條件,第二個(gè)參數(shù)回調(diào)函數(shù)的形式如下function(err){}  

model.remove(conditions, [callback])

  刪除數(shù)據(jù)庫中名稱包括"30"的數(shù)據(jù)

temp.remove({name:/30/},function(err){})

 [注意]remove()方法中的回調(diào)函數(shù)不能省略,否則數(shù)據(jù)不會(huì)被刪除。當(dāng)然,可以使用exec()方法來簡寫代碼

temp.remove({name:/30/}).exec()

  下面介紹文檔的remove()方法,該方法的參數(shù)回調(diào)函數(shù)的形式如下function(err,doc){}

document.remove([callback])

  刪除數(shù)據(jù)庫中名稱包含"huo"的數(shù)據(jù)

  [注意]文檔的remove()方法的回調(diào)函數(shù)參數(shù)可以省略

temp.find({name:/huo/},function(err,doc){
    doc.forEach(function(item,index,arr){
        item.remove(function(err,doc){
            //{ _id: 5971f93be6f98ec60e3dc86c, name: "huochai", age: 30 }
            //{ _id: 5971f93be6f98ec60e3dc86e, name: "huo", age: 60 }
            console.log(doc);
        })
    })
})  

findOneAndRemove()

model的remove()會(huì)刪除符合條件的所有數(shù)據(jù),如果只刪除符合條件的第一條數(shù)據(jù),則可以使用model的findOneAndRemove()方法

Model.findOneAndRemove(conditions, [options], [callback])

  集合temps現(xiàn)有數(shù)據(jù)如下

 現(xiàn)在刪除第一個(gè)年齡小于20的數(shù)據(jù)

temp.findOneAndRemove({age:{$lt:20}},function(err,doc){
    //{ _id: 5972d3f3e6f98ec60e3dc873, name: "wang", age: 18 }
    console.log(doc);
})

與model的remove()方法相同,回調(diào)函數(shù)不能省略,否則數(shù)據(jù)不會(huì)被刪除。當(dāng)然,可以使用exec()方法來簡寫代碼

temp.findOneAndRemove({age:{$lt:20}}).exec()
findByIdAndRemove()
Model.findByIdAndRemove(id, [options], [callback])

刪除第0個(gè)元素

var aIDArr = [];
temp.find(function(err,docs){
    docs.forEach(function(item,index,arr){
        aIDArr.push(item._id);
    })
    temp.findByIdAndRemove(aIDArr[0],function(err,doc){
        //{ _id: 5972d754e6f98ec60e3dc882, name: "huochai", age: 27 }
        console.log(doc);
    })            
})

 類似的,該方法也不能省略回調(diào)函數(shù),否則數(shù)據(jù)不會(huì)被刪除。當(dāng)然,可以使用exec()方法來簡寫代碼

var aIDArr = [];
temp.find(function(err,docs){
    docs.forEach(function(item,index,arr){
        aIDArr.push(item._id);
    })
    temp.findByIdAndRemove(aIDArr[0]).exec()            
})

前后鉤子

 前后鉤子即pre()和post()方法,又稱為中間件,是在執(zhí)行某些操作時(shí)可以執(zhí)行的函數(shù)。中間件在schema上指定,類似于靜態(tài)方法或?qū)嵗椒ǖ?/p>

  可以在數(shù)據(jù)庫執(zhí)行下列操作時(shí),設(shè)置前后鉤子

    validate
    save
    remove
    count
    find
    findOne
    findOneAndRemove
    findOneAndUpdate
    insertMany
    update
pre()

  以find()方法為例,在執(zhí)行find()方法之前,執(zhí)行pre()方法

var schema = new mongoose.Schema({ age:Number, name: String,x:Number,y:Number});  
schema.pre("find",function(next){
    console.log("我是pre方法1");
    next();
});
schema.pre("find",function(next){
    console.log("我是pre方法2");
    next();
});  
var temp = mongoose.model("temp", schema);
temp.find(function(err,docs){
    console.log(docs[0]);
})    
/*
我是pre方法1
我是pre方法2
{ _id: 5972ed35e6f98ec60e3dc886,name: "huochai",age: 27,x: 1,y: 2 }
*/
post()

  post()方法并不是在執(zhí)行某些操作后再去執(zhí)行的方法,而在執(zhí)行某些操作前最后執(zhí)行的方法,post()方法里不可以使用next()

var schema = new mongoose.Schema({ age:Number, name: String,x:Number,y:Number});  
schema.post("find",function(docs){
    console.log("我是post方法1");
});
schema.post("find",function(docs){
    console.log("我是post方法2");
});
var temp = mongoose.model("temp", schema);
temp.find(function(err,docs){
    console.log(docs[0]);
}) 
/*
我是post方法1
我是post方法2
{ _id: 5972ed35e6f98ec60e3dc886,name: "huochai",age: 27,x: 1,y: 2 }
 */   

查詢后處理

常用的查詢后處理的方法如下所示

sort     排序
skip     跳過
limit    限制
select   顯示字段
exect    執(zhí)行
count    計(jì)數(shù)
distinct 去重
var schema = new mongoose.Schema({ age:Number, name: String,x:Number,y:Number});  
var temp = mongoose.model("temp", schema);
temp.find(function(err,docs){
    //[ { _id: 5972ed35e6f98ec60e3dc886,name: "huochai",age: 27,x: 1,y: 2 },
    //{ _id: 5972ed35e6f98ec60e3dc887,name: "wang",age: 18,x: 1,y: 1 },
    //{ _id: 5972ed35e6f98ec60e3dc888, name: "huo", age: 30, x: 2, y: 1 },
    //{ _id: 5972ed35e6f98ec60e3dc889, name: "li", age: 20, x: 2, y: 2 } ]
    console.log(docs);
}) 
sort()

  按age從小到大排序

temp.find().sort("age").exec(function(err,docs){
    //[ { _id: 5972ed35e6f98ec60e3dc887,name: "wang",age: 18,x: 1,y: 1 },
    //{ _id: 5972ed35e6f98ec60e3dc889, name: "li", age: 20, x: 2, y: 2 },
    //{ _id: 5972ed35e6f98ec60e3dc886,name: "huochai",age: 27,x: 1,y: 2 },
    //{ _id: 5972ed35e6f98ec60e3dc888, name: "huo", age: 30, x: 2, y: 1 } ]
    console.log(docs);
}); 

  按x從小到大,age從大到小排列

temp.find().sort("x -age").exec(function(err,docs){
    //[ { _id: 5972ed35e6f98ec60e3dc886,name: "huochai",age: 27,x: 1,y: 2 },
    //{  _id: 5972ed35e6f98ec60e3dc887,name: "wang",age: 18,x: 1,y: 1 },
    //{ _id: 5972ed35e6f98ec60e3dc888, name: "huo", age: 30, x: 2, y: 1 },
    //{ _id: 5972ed35e6f98ec60e3dc889, name: "li", age: 20, x: 2, y: 2 } ]
    console.log(docs);
}); 
skip()

  跳過1個(gè),顯示其他

temp.find().skip(1).exec(function(err,docs){
    //[ { _id: 5972ed35e6f98ec60e3dc887,name: "wang",age: 18,x: 1,y: 1 },
    //{ _id: 5972ed35e6f98ec60e3dc888, name: "huo", age: 30, x: 2, y: 1 },
    //{ _id: 5972ed35e6f98ec60e3dc889, name: "li", age: 20, x: 2, y: 2 } ]
    console.log(docs);
}); 
limit()

  顯示2個(gè)

temp.find().limit(2).exec(function(err,docs){
    //[ { _id: 5972ed35e6f98ec60e3dc886,name: "huochai",age: 27,x: 1,y: 2 },
    //{ _id: 5972ed35e6f98ec60e3dc887,name: "wang",age: 18,x: 1,y: 1 } ]
    console.log(docs);
}); 
select()

  顯示name、age字段,不顯示_id字段

temp.find().select("name age -_id").exec(function(err,docs){
    //[ { name: "huochai", age: 27 },{ name: "wang", age: 18 },{ name: "huo", age: 30 },{ name: "li", age: 20 } ]
    console.log(docs);
}); 
temp.find().select({name:1, age:1, _id:0}).exec(function(err,docs){
    //[ { name: "huochai", age: 27 },{ name: "wang", age: 18 },{ name: "huo", age: 30 },{ name: "li", age: 20 } ]
    console.log(docs);
}); 

  下面將以上方法結(jié)合起來使用,跳過第1個(gè)后,只顯示2個(gè)數(shù)據(jù),按照age由大到小排序,且不顯示_id字段

temp.find().skip(1).limit(2).sort("-age").select("-_id").exec(function(err,docs){
    //[ { name: "huochai", age: 27, x: 1, y: 2 },
    //{ name: "li", age: 20, x: 2, y: 2 } ]
    console.log(docs);
}); 
count()

  顯示集合temps中的文檔數(shù)量

temp.find().count(function(err,count){
    console.log(count);//4
}); 
distinct()

  返回集合temps中的x的值

temp.find().distinct("x",function(err,distinct){
    console.log(distinct);//[ 1, 2 ]
}); 

文檔驗(yàn)證

為什么需要文檔驗(yàn)證呢?以一個(gè)例子作為說明,schema進(jìn)行如下定義

var schema = new mongoose.Schema({ age:Number, name: String,x:Number,y:Number});  

  如果不進(jìn)行文檔驗(yàn)證,保存文檔時(shí),就可以不按照Schema設(shè)置的字段進(jìn)行設(shè)置,分為以下幾種情況

  1、缺少字段的文檔可以保存成功

var temp = mongoose.model("temp", schema);
new temp({age:10}).save(function(err,doc){
    //{ __v: 0, age: 10, _id: 597304442b70086a1ce3cf05 }
    console.log(doc);
}); 

  2、包含未設(shè)置的字段的文檔也可以保存成功,未設(shè)置的字段不被保存

new temp({age:100,abc:"abc"}).save(function(err,doc){
    //{ __v: 0, age: 100, _id: 5973046a2bb57565b474f48b }
    console.log(doc);
}); 

  3、包含字段類型與設(shè)置不同的字段的文檔也可以保存成功,不同字段類型的字段被保存為設(shè)置的字段類型

new temp({age:true,name:10}).save(function(err,doc){
    //{ __v: 0, age: 1, name: "10", _id: 597304f7a926033060255366 }
    console.log(doc);
}); 

  而通過文檔驗(yàn)證,就可以避免以下幾種情況發(fā)生

  文檔驗(yàn)證在SchemaType中定義,格式如下

{name: {type:String, validator:value}}

  常用驗(yàn)證包括以下幾種

required: 數(shù)據(jù)必須填寫
default: 默認(rèn)值
validate: 自定義匹配
min: 最小值(只適用于數(shù)字)
max: 最大值(只適用于數(shù)字)
match: 正則匹配(只適用于字符串)
enum:  枚舉匹配(只適用于字符串)
required

  將age設(shè)置為必填字段,如果沒有age字段,文檔將不被保存,且出現(xiàn)錯(cuò)誤提示

var schema = new mongoose.Schema({ age:{type:Number,required:true}, name: String,x:Number,y:Number});  
var temp = mongoose.model("temp", schema);
new temp({name:"abc"}).save(function(err,doc){
    //Path `age` is required.
    console.log(err.errors["age"].message);
}); 
default

  設(shè)置age字段的默認(rèn)值為18,如果不設(shè)置age字段,則會(huì)取默認(rèn)值

var schema = new mongoose.Schema({ age:{type:Number,default:18}, name:String,x:Number,y:Number});  
var temp = mongoose.model("temp", schema);
new temp({name:"a"}).save(function(err,doc){
    //{ __v: 0, name: "a", _id: 59730d2e7a751d81582210c1, age: 18 }
    console.log(doc);
}); 
min | max

  將age的取值范圍設(shè)置為[0,10]。如果age取值為20,文檔將不被保存,且出現(xiàn)錯(cuò)誤提示

var schema = new mongoose.Schema({ age:{type:Number,min:0,max:10}, name: String,x:Number,y:Number});  
var temp = mongoose.model("temp", schema);
new temp({age:20}).save(function(err,doc){
    //Path `age` (20) is more than maximum allowed value (10).
    console.log(err.errors["age"].message);
}); 
match

  將name的match設(shè)置為必須存在"a"字符。如果name不存在"a",文檔將不被保存,且出現(xiàn)錯(cuò)誤提示

var schema = new mongoose.Schema({ age:Number, name:{type:String,match:/a/},x:Number,y:Number});  
var temp = mongoose.model("temp", schema);
new temp({name:"bbb"}).save(function(err,doc){
    //Path `name` is invalid (bbb).
    console.log(err.errors["name"].message);
}); 
enum

  將name的枚舉取值設(shè)置為["a","b","c"],如果name不在枚舉范圍內(nèi)取值,文檔將不被保存,且出現(xiàn)錯(cuò)誤提示

var schema = new mongoose.Schema({ age:Number, name:{type:String,enum:["a","b","c"]},x:Number,y:Number});  
var temp = mongoose.model("temp", schema);
new temp({name:"bbb"}).save(function(err,doc){
    //`bbb` is not a valid enum value for path `name`.
    console.log(err.errors["name"].message);

}); 
validate

  validate實(shí)際上是一個(gè)函數(shù),函數(shù)的參數(shù)代表當(dāng)前字段,返回true表示通過驗(yàn)證,返回false表示未通過驗(yàn)證。利用validate可以自定義任何條件。比如,定義名字name的長度必須在4個(gè)字符以上

var validateLength = function(arg){
    if(arg.length > 4){
        return true;
    }
    return false;
};
var schema = new mongoose.Schema({ name:{type:String,validate:validateLength}, age:Number,x:Number,y:Number});  
var temp = mongoose.model("temp", schema);
new temp({name:"abc"}).save(function(err,doc){
    //Validator failed for path `name` with value `abc`
    console.log(err.errors["name"].message);
}); 

練習(xí)

本節(jié)引用 mongoose的基本使用 有刪改

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

編輯 test.js :

var mongoose = require("mongoose");
var db = mongoose.connect("mongodb://127.0.0.1:27017/test");
db.connection.on("error", function(error){
  console.log("數(shù)據(jù)庫test連接失敗:" + error);
});
db.connection.on("open", function(){
  console.log("數(shù)據(jù)庫test連接成功");
});

接著先打開一個(gè) iTerm2 終端,開啟 mongodb 服務(wù):

mongod

再打開另一個(gè) iTerm2 終端,運(yùn)行 test.js:

node test.js
//成功后便會(huì)輸出:數(shù)據(jù)庫test連接成功
Schema/Model/Entity

沒有比文檔更詳細(xì)的了:http://mongoosejs.com/docs/gu...

Schema:數(shù)據(jù)庫集合的結(jié)構(gòu)對(duì)象。
Model :由Schema構(gòu)造而成,可操作數(shù)據(jù)庫。
Entity:由Model創(chuàng)建的實(shí)體,可操作數(shù)據(jù)庫。

看完文檔后,再看看下面一段代碼配合理解一下:

var mongoose = require("mongoose");
var db = mongoose.connect("mongodb://127.0.0.1:27017/test");
// var testModel = db.model("test1", testSchema); // 集合名稱;集合的結(jié)構(gòu)對(duì)象
var TestSchema = new mongoose.Schema({
    name : { type:String },
    age  : { type:Number, default:0 },
    email: { type:String },
    time : { type:Date, default:Date.now }
});
var TestModel = db.model("test1", TestSchema );
var TestEntity = new TestModel({
    name : "helloworld",
    age  : 28,
    email: "helloworld@qq.com"
});
TestEntity.save(function(error,doc){
  if(error){
     console.log("error :" + error);
  }else{
     console.log(doc);
  }
});
model 數(shù)據(jù)插入

在前面的數(shù)據(jù)庫連接成功的前提下,我們?cè)跀?shù)據(jù)庫 test 下新建一個(gè)集合 test1 、并往里面插入保存一組數(shù)據(jù):

var testSchema = new mongoose.Schema({
  name: {type: String},
  age: {type: Number, default: 0},
  email: {type: String},
  time: {type: Date, default: Date.now}
});
var testModel = db.model("test1", testSchema); // 集合名稱;集合的結(jié)構(gòu)對(duì)象
// Document文檔(關(guān)聯(lián)數(shù)組式的對(duì)象) < Collection集合 < 數(shù)據(jù)庫
// 插入保存一段數(shù)據(jù)
testModel.create([
  {name: "test1", age: 8},
  {name: "test2", age: 18},
  {name: "test3", age: 28},
  {name: "test4", age: 38},
  {name: "test5", age: 48},
  {name: "test6", age: 58, email:"tttt@qq.com"},
  {name: "test7", age: 68, email:"ssss@qq.com"},
  {name: "test8", age: 18},
  {name: "test9", age: 18, email:"rrrr@qq.com"},
  {name: "test10",age: 18}
], function (error, docs) {
  if(error) {
    console.log(error);
  } else {
    console.log("save ok");
    console.log(docs);
  }
});
find 數(shù)據(jù)查詢

mongoose 提供了find、findOne、和findById方法用于文檔查詢。
基本語法:

model.find(Conditions,fields,options,callback(err, doc));
// Conditions: 查詢條件
// fields: 返回的字段
// options: 游標(biāo)(sort,limit)
// callback: 回調(diào)函數(shù),參數(shù)doc為查詢出來的結(jié)果

條件查詢的基礎(chǔ):

$lt (小于<)
$lte (小于等于<=)
$gt (大于>)
$gte (大于等于>=)
$ne (不等于,不包含!=)
$in (包含)
$or (查詢多個(gè)鍵值的任意給定值)
$exists (判斷某些屬性是否存在)
$all (全部)

具體的一些實(shí)例,代碼里已有詳細(xì)注釋:

// find(Conditions,fields,callback);
// 省略或?yàn)榭铡⒎祷厮杏涗洠恢话琻ame,age字段,去掉默認(rèn)的_id字段;執(zhí)行回調(diào)函數(shù)
testModel.find({}, {name:1, age:1, _id:0}, function(err, docs){
  if (err) {
    console.log("查詢出錯(cuò):" + err);
  } else {
    console.log("{}查詢結(jié)果為:");
    console.log(docs);
  }
});
----
{}查詢結(jié)果為:
[ { name: "test3", age: 28 },
  { name: "test2", age: 18 },
  { name: "test1", age: 8 },
  { name: "test6", age: 58 },
  { name: "test4", age: 38 },
  { name: "test7", age: 68 },
  { name: "test8", age: 18 },
  { name: "test9", age: 18 },
  { name: "test5", age: 48 },
  { name: "test10", age: 18 } ]
----
// 查詢age大于等于28,小于等于48
testModel.find({age: {$gte: 28, $lte: 48}}, {name:1, age:1, _id:0}, function(err, docs){
  if (err) {
    console.log("查詢出錯(cuò):" + err);
  } else {
    console.log("$gte,$lte查詢結(jié)果為:");
    console.log(docs);
  }
});
----
$gte,$lte查詢結(jié)果為:
[ { name: "test3", age: 28 },
  { name: "test4", age: 38 },
  { name: "test5", age: 48 } ]
----
// 查詢age為58、68的2條數(shù)據(jù)
testModel.find({age: {$in: [58, 68]}}, {name:1, age:1, _id:0}, function(err, docs){
  if (err) {
    console.log("查詢出錯(cuò):" + err);
  } else {
    console.log("$in查詢結(jié)果為:");
    console.log(docs);
  }
});
----
$in查詢結(jié)果為:
[ { name: "test6", age: 58 }, { name: "test7", age: 68 } ]
----
// 查詢name為test3、或者age為18的全部數(shù)據(jù)
testModel.find({$or: [{name: "test3"}, {age: 18}]}, {name:1, age:1, _id:0}, function(err, docs){
  if (err) {
    console.log("查詢出錯(cuò):" + err);
  } else {
    console.log("$or查詢結(jié)果為:");
    console.log(docs);
  }
});
----
$or查詢結(jié)果為:
[ { name: "test3", age: 28 },
  { name: "test2", age: 18 },
  { name: "test8", age: 18 },
  { name: "test9", age: 18 },
  { name: "test10", age: 18 } ]
----

// step3:游標(biāo)查詢
// 查詢name為test3、或者age為18的全部數(shù)據(jù);但限制只查詢2條數(shù)據(jù)
testModel.find({$or: [{name: "test3"}, {age: 18}]}, {name:1, age:1, _id:0}, {limit: 2}, function(err, docs){
  if (err) {
    console.log("查詢出錯(cuò):" + err);
  } else {
    console.log("limit查詢結(jié)果為:");
    console.log(docs);
  }
});
----
limit查詢結(jié)果為:
[ { name: "test3", age: 28 }, { name: "test2", age: 18 } ]
----

//查詢age大于等于28,小于等于48;降序輸出
testModel.find({age: {$gte: 28, $lte: 48}}, {name:1, age:1, _id:0}, {sort: {age: -1}}, function(err, docs){
  if (err) {
    console.log("查詢出錯(cuò):" + err);
  } else {
    console.log("sort查詢結(jié)果為:");
    console.log(docs);
  }
});
----
sort查詢結(jié)果為:
[ { name: "test5", age: 48 },
  { name: "test4", age: 38 },
  { name: "test3", age: 28 } ]
----
update 數(shù)據(jù)更新

基本使用:model.update(查詢條件,更新對(duì)象,callback);

var conditions = {name: "test1"};
var update = {$set: {age: 11 }};
testModel.update(conditions, update, function(error){
  if(error) {
    console.log(error);
  } else {
    console.log("Update success!");
    testModel.find({name: "test1"}, {name:1, age:1, _id:0}, function(err, docs){
      if (err) {
        console.log("查詢出錯(cuò):" + err);
      } else {
        console.log("更新test1后的查詢結(jié)果為:");
        console.log(docs);  
        // 更新test_update后的查詢結(jié)果為空數(shù)組:[ ];
        // 更新test1后的查詢結(jié)果為: [ { name: "test1", age: 11 } ]
        // 只能更新本來已存在的數(shù)據(jù)
      }
    });
  }
---
Update success!
更新test1后的查詢結(jié)果為:
[ { name: "test1", age: 11 } ]
---
remove 數(shù)據(jù)刪除

基本使用:model.remove(查詢條件,callback);

var conditions = {name: "test2"};
testModel.remove(conditions, function(error){
  if(error) {
    console.log(error);
  } else {
    console.log("Delete success!");
    testModel.find({name: "test2"}, {name:1, age:1, _id:0}, function(err, docs){
      if (err) {
        console.log("查詢出錯(cuò):" + err);
      } else {
        console.log("刪除test2后的查詢結(jié)果為:");
        console.log(docs);  // 刪除test2后的查詢結(jié)果為空數(shù)組:[ ];
      }
    });
  }
});
----
Delete success!
刪除test2后的查詢結(jié)果為:
[]
----

參考引用

http://mongoosejs.com

Mongoose簡要API

Nodejs學(xué)習(xí)筆記(十四)— Mongoose介紹和入門

Mongoose基礎(chǔ)入門

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/17658.html

相關(guān)文章

  • GraphQL 搭配 Koa 最佳入門實(shí)踐

    摘要:如下圖嗯,如圖都已經(jīng)查詢到我們保存的全部數(shù)據(jù),并且全部返回前端了。如圖沒錯(cuò),什么都沒有就是查詢服務(wù)的界面。寫好了之后我們?cè)谂渲靡幌侣酚桑M(jìn)入里面,加入下面幾行代碼。 GraphQL一種用為你 API 而生的查詢語言,2018已經(jīng)到來,PWA還沒有大量投入生產(chǎn)應(yīng)用之中就已經(jīng)火起來了,GraphQL的應(yīng)用或許也不會(huì)太遠(yuǎn)了。前端的發(fā)展的最大一個(gè)特點(diǎn)就是變化快,有時(shí)候應(yīng)對(duì)各種需求場景的變化,不...

    MoAir 評(píng)論0 收藏0
  • 「全棧初探」- Mongoose的簡單使用

    摘要:下載依賴包完成項(xiàng)目創(chuàng)建,項(xiàng)目結(jié)構(gòu)連接數(shù)據(jù)庫在根目錄下創(chuàng)建,輸入以下代碼,監(jiān)聽的幾個(gè)事件,如果以上操作都沒錯(cuò)的話,那么就會(huì)監(jiān)聽第一個(gè)事件事件,表示連接數(shù)據(jù)庫成功,在最后,我們導(dǎo)出對(duì)象,以供其他模塊使用。 一、準(zhǔn)備工作 1. 啟動(dòng)mongo數(shù)據(jù)庫 關(guān)于下載安裝啟動(dòng)數(shù)據(jù)庫我這里就不做過多解釋,谷歌下會(huì)有很多教程,啟動(dòng)成功后的命令窗如下所示: showImg(https://segmentfa...

    vboy1010 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<