模塊-mongoose

mongoose:nodejs上簡(jiǎn)潔的mongodb對(duì)象模型坡贺。為什么要做mongoose旺矾,當(dāng)我們使用mongodb的時(shí)候片任,需要面對(duì)確認(rèn)器贩、投遞和商務(wù)邏輯等阻力颅夺,mongoose為此做了非常大的簡(jiǎn)化,非常簡(jiǎn)潔和優(yōu)美蛹稍。如下所示:

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

var Cat = mongoose.model('Cat', { name: String });

var kitty = new Cat({ name: 'Zildjian' });
kitty.save(function (err) {
  if (err) {
    console.log(err);
  } else {
    console.log('meow');
  }
});

使用mongoose

首先確認(rèn)已經(jīng)安裝了MongoDBNode.js吧黄,下一步通過npm安裝Mongoose:

$ npm install mongoose

接下來我們要做的就是MongoDB數(shù)據(jù)庫的連接和連接信息的監(jiān)聽:

// getting-started.js
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() {
  // we're connected!
});

一旦連接被打開,回調(diào)將會(huì)被調(diào)用唆姐。我們的代碼需要關(guān)注的就是在回調(diào)中進(jìn)行處理拗慨。對(duì)于Mongoose,所有的數(shù)據(jù)來源于 Schema奉芦。我們需要定義自己的Schema赵抢。

var kittySchema = mongoose.Schema({
    name: String
});
var Kitten = mongoose.model('Kitten', kittySchema);

對(duì)于已經(jīng)定義的數(shù)據(jù)模型操作是非常簡(jiǎn)單的:

var silence = new Kitten({ name: 'Silence' });
console.log(silence.name); // 'Silence'

也可以為Schema模型定義函數(shù):

kittySchema.methods.speak = function () {
  var greeting = this.name
    ? "Meow name is " + this.name
    : "I don't have a name";
  console.log(greeting);
}
var Kitten = mongoose.model('Kitten', kittySchema);
var fluffy = new Kitten({ name: 'fluffy' });
fluffy.speak(); // "Meow name is fluffy"

如果我們期望文檔存儲(chǔ)至數(shù)據(jù)庫:

fluffy.save(function (err, fluffy) {
  if (err) return console.error(err);
  fluffy.speak();
});

查詢文檔:

Kitten.find(function (err, kittens) {
  if (err) return console.error(err);
  console.log(kittens);
})
// 或者使用正則匹配,搜索所有文檔中名稱屬性中包含fluff字段的声功,在callback返回?cái)?shù)組結(jié)果
Kitten.find({ name: /^fluff/ }, callback);

mongoose的操作

Schema

一種以文件形式存儲(chǔ)的數(shù)據(jù)庫模型骨架烦却,無法直接通往數(shù)據(jù)庫端,也就是說它不具備對(duì)數(shù)據(jù)庫的操作能力.可以說是數(shù)據(jù)屬性模型(傳統(tǒng)意義的表結(jié)構(gòu))先巴,又或著是“集合”的模型骨架.

/* 定義一個(gè) Schema */
var mongoose = require("mongoose");

var TestSchema = new mongoose.Schema({
    name : { type:String },//屬性name,類型為String
    age  : { type:Number, default:0 },//屬性age,類型為Number,默認(rèn)為0
    time : { type:Date, default:Date.now },
    email: { type:String,default:''}
});

上面這個(gè) TestSchema包含4個(gè)屬性 [name, age, time, email]

Model

由Schema構(gòu)造生成的模型其爵,除了Schema定義的數(shù)據(jù)庫骨架以外冒冬,還具有數(shù)據(jù)庫操作的行為,類似于管理數(shù)據(jù)庫屬性摩渺、行為的類:

var db = mongoose.connect("mongodb://127.0.0.1:27017/test");

// 創(chuàng)建Model
var TestModel = db.model("test1", TestSchema);

test1 數(shù)據(jù)庫中的集合名稱, 不存在會(huì)創(chuàng)建.

Entity

由Model創(chuàng)建的實(shí)體简烤,使用save方法保存數(shù)據(jù),Model和Entity都有能影響數(shù)據(jù)庫的操作摇幻,但Model比Entity更具操作性

var TestEntity = new TestModel({
       name : "Lenka",
       age  : 36,
       email: "lenka@qq.com"
});
console.log(TestEntity.name); // Lenka
console.log(TestEntity.age); // 36

ObjectId

存儲(chǔ)在mongodb集合中的每個(gè)文檔(document)都有一個(gè)默認(rèn)的主鍵_id横侦,這個(gè)主鍵名稱是固定的,它可以是mongodb支持的任何數(shù)據(jù)類型绰姻,默認(rèn)是ObjectId丈咐。

ObjectId是一個(gè)12字節(jié)的 BSON 類型字符串。按照字節(jié)順序龙宏,依次代表:
4字節(jié):UNIX時(shí)間戳
3字節(jié):表示運(yùn)行MongoDB的機(jī)器
2字節(jié):表示生成此_id的進(jìn)程
3字節(jié):由一個(gè)隨機(jī)數(shù)開始的計(jì)數(shù)器生成的值

Schema - 表結(jié)構(gòu)

1.構(gòu)造函數(shù)

 new mongoose.Schema( { name:{type:String}, age:{type:Number, default:10}  } )

2.添加屬性

 Schema.add( { name: ‘String’, email: ‘String’, age: ‘Number’ } )

3.有時(shí)候Schema不僅要為后面的Model和Entity提供公共的屬性棵逊,還要提供公共的方法

 Schema.method( ‘say’, function(){console.log(‘hello’);} )
//這樣Model和Entity的實(shí)例就能使用這個(gè)方法了

4.添加靜態(tài)方法

 Schema.static( ‘say’, function(){console.log(‘hello’);} )
//靜態(tài)方法,只限于在Model層就能使用

5.追加方法

 Schema.methods.say = function(){console.log(‘hello’);};
//靜態(tài)方法银酗,只限于在Model層就能使用

model - 文檔操作

1.構(gòu)造函數(shù), 參數(shù)1:集合名稱, 參數(shù)2:Schema實(shí)例

 db.model(“test1”, TestSchema );

2.查詢, 參數(shù)1忽略,或?yàn)榭諏?duì)象則返回所有集合文檔

 model.find({}, callback);

 model.find({},field,callback);
過濾查詢,參數(shù)2: {‘name’:1, ‘a(chǎn)ge’:0} 查詢文檔的返回結(jié)果包含name , 不包含age.(_id默認(rèn)是1)

 model.find({},null,{limit:20});
過濾查詢,參數(shù)3: 游標(biāo)操作 limit限制返回結(jié)果數(shù)量為20個(gè),如不足20個(gè)則返回所有.

 model.findOne({}, callback);
查詢找到的第一個(gè)文檔

 model.findById(‘obj._id’, callback);
查詢找到的第一個(gè)文檔,同上. 但是只接受 __id 的值查詢

3.創(chuàng)建, 在集合中創(chuàng)建一個(gè)文檔

 Model.create(文檔數(shù)據(jù), callback))

4.更新,參數(shù)1:查詢條件, 參數(shù)2:更新對(duì)象,可以使用MondoDB的更新修改器

 Model.update(conditions, update, function(error)

5.刪除, 參數(shù)1:查詢條件

 Model.remove(conditions,callback);

Entity - 文檔操作

1.構(gòu)造函數(shù), 其實(shí)就是model的實(shí)例

 new TestModel( { name:‘xueyou’, age:21 } );

2.創(chuàng)建, 在集合中創(chuàng)建一個(gè)文檔.

 Entity.save(callback);

修改器和更新器

更新修改器:

‘$inc’ 增減修改器,只對(duì)數(shù)字有效.下面的實(shí)例: 找到 age=22的文檔,修改文檔的age值自增1

 Model.update({‘a(chǎn)ge’:22}, {’$inc’:{‘a(chǎn)ge’:1} }  );
執(zhí)行后: age=23

‘$set’ 指定一個(gè)鍵的值,這個(gè)鍵不存在就創(chuàng)建它.可以是任何MondoDB支持的類型.

 Model.update({‘a(chǎn)ge’:22}, {’$set’:{‘a(chǎn)ge’:‘haha’} }  );
執(zhí)行后: age=‘haha’

‘$unset’ 同上取反,刪除一個(gè)鍵

 Model.update({‘a(chǎn)ge’:22}, {’$unset’:{‘a(chǎn)ge’:‘haha’} }  );
執(zhí)行后: age鍵不存在

數(shù)組修改器:

‘$push’ 給一個(gè)鍵push一個(gè)數(shù)組成員,鍵不存在會(huì)創(chuàng)建

 Model.update({‘a(chǎn)ge’:22}, {’$push’:{‘a(chǎn)rray’:10} }  );
執(zhí)行后: 增加一個(gè) array 鍵,類型為數(shù)組, 有一個(gè)成員 10

‘$addToSet’ 向數(shù)組中添加一個(gè)元素,如果存在就不添加

 Model.update({‘a(chǎn)ge’:22}, {’$addToSet’:{‘a(chǎn)rray’:10} }  );
執(zhí)行后: array中有10所以不會(huì)添加

‘$each’ 遍歷數(shù)組, 和 $push 修改器配合可以插入多個(gè)值

 Model.update({‘a(chǎn)ge’:22}, {’$push’:{‘a(chǎn)rray’:{’$each’: [1,2,3,4,5]}} }  );
執(zhí)行后: array : [10,1,2,3,4,5]

‘$pop’ 向數(shù)組中尾部刪除一個(gè)元素

 Model.update({‘a(chǎn)ge’:22}, {’$pop’:{‘a(chǎn)rray’:1} }  );
執(zhí)行后: array : [10,1,2,3,4]  tips: 將1改成-1可以刪除數(shù)組首部元素

‘$pull’ 向數(shù)組中刪除指定元素

 Model.update({‘a(chǎn)ge’:22}, {’$pull’:{‘a(chǎn)rray’:10} }  );
執(zhí)行后: array : [1,2,3,4]  匹配到array中的10后將其刪除

條件查詢:

“$lt” 小于
“$lte” 小于等于
“$gt” 大于
“$gte” 大于等于
“$ne” 不等于

 Model.find({“age”:{ “$get”:18 , “$lte”:30 } } );
查詢 age 大于等于18并小于等于30的文檔

或查詢 OR:

‘$in’ 一個(gè)鍵對(duì)應(yīng)多個(gè)值
‘$nin’ 同上取反, 一個(gè)鍵不對(duì)應(yīng)指定值
“$or” 多個(gè)條件匹配, 可以嵌套 $in 使用
“$not” 同上取反, 查詢與特定模式不匹配的文檔

 Model.find({“age”:{ “$in”:[20,21,22.‘haha’]} } );
查詢 age等于20或21或21或’haha’的文檔

 Model.find({"$or" :  [ {‘a(chǎn)ge’:18} , {‘name’:‘xueyou’} ] });
查詢 age等于18 或 name等于’xueyou’ 的文檔

類型查詢:

null 能匹配自身和不存在的值, 想要匹配鍵的值 為null, 就要通過 “$exists” 條件判定鍵值已經(jīng)存在
"$exists" (表示是否存在的意思)

Model.find(“age” :  { “$in” : [null] , “exists” : true  } );
查詢 age值為null的文檔

Model.find({name: {$exists: true}},function(error,docs){
  //查詢所有存在name屬性的文檔
});

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

正則表達(dá)式:

MongoDb 使用 Prel兼容的正則表達(dá)式庫來匹配正則表達(dá)式

 find( {“name” : /joe/i } ) 
查詢name為 joe 的文檔, 并忽略大小寫

 find( {“name” : /joe?/i } )
查詢匹配各種大小寫組合

查詢數(shù)組:

Model.find({“array”:10} );
查詢 array(數(shù)組類型)鍵中有10的文檔,  array : [1,2,3,4,5,10]  會(huì)匹配到

 Model.find({“array[5]”:10} );
查詢 array(數(shù)組類型)鍵中下標(biāo)5對(duì)應(yīng)的值是10,  array : [1,2,3,4,5,10]  會(huì)匹配到

‘$all’ 匹配數(shù)組中多個(gè)元素

 Model.find({“array”:[5,10]} );
查詢 匹配array數(shù)組中 既有5又有10的文檔

‘$size’ 匹配數(shù)組長(zhǎng)度

 Model.find({“array”:{"$size" : 3} } );
查詢 匹配array數(shù)組長(zhǎng)度為3 的文檔

‘$slice’ 查詢子集合返回

 Model.find({“array”:{"$skice" : 10} } );
查詢 匹配array數(shù)組的前10個(gè)元素

 Model.find({“array”:{"$skice" : [5,10] } } );
查詢 匹配array數(shù)組的第5個(gè)到第10個(gè)元素

where

用它可以執(zhí)行任意javacript語句作為查詢的一部分,如果回調(diào)函數(shù)返回 true 文檔就作為結(jié)果的一部分返回

    find( {"$where" : function(){
        for( var x in this ){
         //這個(gè)函數(shù)中的 this 就是文檔
        }
        
        if(this.x !== null && this.y !== null){
            return this.x + this.y === 10 ? true : false;
        }else{
            return true;
        }
}  }  )

簡(jiǎn)化版本

    find( {"$where" :  "this.x + this.y === 10" } )
    find( {"$where" : " function(){ return this.x + this.y ===10; } " } )

游標(biāo):

limit(3) 限制返回結(jié)果的數(shù)量,
skip(3) 跳過前3個(gè)文檔,返回其余的
sort( {“username”:1 , “age”:-1 } ) 排序 鍵對(duì)應(yīng)文檔的鍵名, 值代表排序方向, 1 升序, -1降序

補(bǔ)充:

使用rename

db.students.update( { _id: 1 }, { $rename: { 'nickname': 'alias', 'cell': 'mobile' } } )

批量appkey改成appid

db.app.update({},{$rename:{"appkey":"appid"}},{multi:true})

參考:
http://mongoosejs.com/docs/guide.html
https://cnodejs.org/topic/548e54d157fd3ae46b233502

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辆影,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子黍特,更是在濱河造成了極大的恐慌蛙讥,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灭衷,死亡現(xiàn)場(chǎng)離奇詭異次慢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)翔曲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門迫像,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瞳遍,你說我怎么就攤上這事闻妓。” “怎么了掠械?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵由缆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我猾蒂,道長(zhǎng)均唉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任肚菠,我火速辦了婚禮舔箭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘案糙。我一直安慰自己限嫌,他們只是感情好靴庆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怒医,像睡著了一般炉抒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上稚叹,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天焰薄,我揣著相機(jī)與錄音,去河邊找鬼扒袖。 笑死塞茅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的季率。 我是一名探鬼主播野瘦,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼飒泻!你這毒婦竟也來了鞭光?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤泞遗,失蹤者是張志新(化名)和其女友劉穎惰许,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體史辙,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汹买,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了聊倔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晦毙。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖方库,靈堂內(nèi)的尸體忽然破棺而出结序,到底是詐尸還是另有隱情障斋,我是刑警寧澤纵潦,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站垃环,受9級(jí)特大地震影響邀层,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜遂庄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一寥院、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涛目,春花似錦秸谢、人聲如沸凛澎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽塑煎。三九已至,卻和暖如春臭蚁,著一層夾襖步出監(jiān)牢的瞬間最铁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工垮兑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冷尉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓系枪,卻偏偏與公主長(zhǎng)得像雀哨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子私爷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • mongoDB簡(jiǎn)介 mongoDB與一些關(guān)系型數(shù)據(jù)庫相比震束,它更顯得輕巧、靈活当犯,非常適合在數(shù)據(jù)規(guī)模很大垢村、事務(wù)性不強(qiáng)的...
    Dr老爹閱讀 1,104評(píng)論 0 2
  • Mongodb 配置選項(xiàng) 通常在mongod.conf中 配置文件 設(shè)置了配置文件后啟動(dòng)時(shí)以自定義的配置文件啟動(dòng):...
    AkaTBS閱讀 1,081評(píng)論 0 6
  • 原文地址 本文簡(jiǎn)單的介紹了數(shù)據(jù)庫,以及如何在 Node/Express 中應(yīng)用他們嚎卫。之后展示如何使用Mongoos...
    前端幼兒班閱讀 5,166評(píng)論 1 5
  • MongoDB 1. MongoDB 是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫嘉栓。由 C++ 語言編寫。旨在為 WEB 應(yīng)用...
    Kevinr閱讀 1,563評(píng)論 0 3
  • VR的原理和實(shí)現(xiàn) 一拓诸、 VR內(nèi)容制作 VR內(nèi)容場(chǎng)景的呈現(xiàn)分為兩種情況:實(shí)景拍攝與3D建模場(chǎng)景制作侵佃。其中,3d建模場(chǎng)...
    JZ_1a90閱讀 5,446評(píng)論 0 1