Node學習筆記三:Hello MongoDB

1.安裝

1.1 使用brew安裝

Mac 上面比較簡便的安裝方法是使用brew
由于網(wǎng)絡(luò)環(huán)境的限制,安裝的時候可以設(shè)置代理

http_proxy=https://ip:port brew install mongodb

如果報錯,先升級 brew

http_proxy=https://ip:port brew update

如果還是沒有用库继,可以通過設(shè)置好代理的瀏覽器中輸入brew請求的下載地址,進行下載。下載完畢后禽绪,將mongodb-3.0.6.yosemite.bottle.tar.gz移動到Library/Caches/Homebrew中(此目錄存放著brew下載好包文件)再重新執(zhí)行 brew install mongodb

測試是否安裝成功,執(zhí)行命令mongod

mongod
2015-09-14T09:00:32.799+0800 I STORAGE  [initandlisten] exception in initAndListen: 29 Data directory /data/db not found., terminating
2015-09-14T09:00:32.800+0800 I CONTROL  [initandlisten] dbexit:  rc: 100

從提示可以看出,需要創(chuàng)建/data/db目錄洪规,現(xiàn)在我們設(shè)置一下印屁,執(zhí)行以下兩行命令:

 sudo mkdir -p /data/db
 sudo chown `id -u` /data/db

-p是如果當前的父級目錄不存在則創(chuàng)建它;
id -u是將所有者指定到當前用戶斩例;用whoami也起相同的效果雄人;

  sudo chown `whoami` /data/db

最后再執(zhí)行一下mongod就可以看到效果了;

mongod

參考資料:https://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/

1.2 安裝可視化工具mongohub

https://github.com/jeromelebel/MongoHub-Mac 下載MongoHub.zip文件,解壓后拖入到應(yīng)用程序中即可使用念赶。使用起來也非常方便础钠,摸一摸就會了。

2.使用MongoDB

2.1 使用mongodb 模塊

安裝mongodb模塊

npm install mongodb 

打開app.js文件叉谜,添加以下代碼旗吁;

//引入模塊
var mongodb = require('mongodb');

//創(chuàng)建一個連接實例,連接到MongoDB服務(wù)器
//主機的地址為localhost停局、端口號未27017很钓。
//auto_reconnect:true,表示在鏈接中斷后能夠自動重新連接
var dbServer =new mongodb.Server('localhost', 27017,{auto_reconnect:true})董栽;

//創(chuàng)建一個數(shù)據(jù)庫名為mydb
//第二個參數(shù)是上面創(chuàng)建的連接實例
//{w:1}是配置
var db = new mongodb.Db('mydb',dbServer,{w:1});

{w:1}是寫入相關(guān)設(shè)置码倦,表明這個是主mongod實例,只要你的 服務(wù)器上不超過一個MongoDB實例锭碳,就可以這樣寫袁稽。更多請參考:http://docs.mongodb.org/master/core/write-concern/

2. 2添加數(shù)據(jù)

首先我們要解釋一下概念:Mongodb的結(jié)構(gòu)中的“數(shù)據(jù)庫”、“集合”擒抛、“文檔”分別對應(yīng)關(guān)系型數(shù)據(jù)庫的:“數(shù)據(jù)庫”推汽、“表”、“行”的概念歧沪。

db.open(function(err,conn){
});

db.open()用于打開數(shù)據(jù)庫歹撒,內(nèi)部參數(shù)是一個異步回調(diào)函數(shù)

db.open(function(err,conn){
    //創(chuàng)建一個名為myCollection的集合
    db.collection('myCollection',function(err, collection){
        var count = 0;
        for (var i=0;i<5;i++){
            //插入一個文檔到集合
            collection.insert({
                num:i
            },function(err,result){
               //輸出結(jié)果
                console.log(result);
                //添加計數(shù)
                count++;
                //如果計數(shù)器足夠大,則關(guān)閉鏈接
                if(count>4){
                    db.close();
                }
            });
        }
    });
});

collection.insert({},function(err,result){})第一個參數(shù)是要插入的內(nèi)容槽畔,第二個參數(shù)是插入成功時的回調(diào)函數(shù)栈妆;由于是插入數(shù)據(jù)不是順序執(zhí)行的,也就是說i=1可能會最后一個插入完成,整個插入順序可能是3鳞尔、4嬉橙、2、1寥假,如果通過if(i>4){}來判斷何時執(zhí)行斷開市框,可能會導(dǎo)致提前斷開。因此需要添加一個外部計數(shù)器糕韧,每次插入成功后count加一枫振,當count大于4的時候斷開連接。

2.3 讀取數(shù)據(jù)

2.3.1 讀取所有數(shù)據(jù)

修改剛才的db.open()中的代碼萤彩,使用collection.find()讀取數(shù)據(jù):

db.open(function(err,conn){
    //選擇集合
    db.collection('myCollection',function(err, collection){
        // 選擇集合中所有的文檔
        collection.find().toArray(function(err,result){
           //輸出數(shù)據(jù)
            console.log(result);
            //關(guān)閉鏈接
            db.close();
        });
    });
});

輸出數(shù)據(jù)粪滤,如下:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 0 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 2 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]

我們可以看出,雖然插入數(shù)據(jù)時結(jié)束的時間是無序的雀扶,但是插入時候的MongoDB的ID是有序的杖小。

2.3.2 讀取特定數(shù)據(jù):

collection.find()沒有特定參數(shù)時,為選擇所有愚墓;如果需要選擇查詢特定內(nèi)容時可以添加參數(shù)予权,例如我們要查詢num為2的所有數(shù)據(jù)可以設(shè)置find()為find({num:2}),mongodb會返回所有滿足條件的數(shù)據(jù)浪册,由于我們只有一條滿足需求的數(shù)據(jù)扫腺,因此返回的集合中只有一條數(shù)據(jù):

[ { _id: 55f65ff1ae0f94286cdabf19, num: 2 } ]

明明是一條數(shù)據(jù),能不能不以集合的方式返回呢村象?
我們可以使用findOne()方法

 collection.findOne({num:2},{},function(err,result){
               console.log(result);
               db.close({});
           });

返回結(jié)果

{ _id: 55f65ff1ae0f94286cdabf19, num: 2 } 
范圍條件查詢

如果我們要查詢所有num>2的數(shù)據(jù)笆环,我們可以將find()參數(shù)設(shè)置為{num:{$gt:2}} $gt 操作符是great than 的縮寫,運行后MongoDB返回兩條數(shù)據(jù):

[ { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]

如果我們要查詢num<2的數(shù)據(jù)煞肾,我們可以使用$lt lt 是little than 的縮寫咧织;設(shè)置find({num:{$lt:2}})嗓袱,返回結(jié)果:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 0 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 } ]

$gt$lt可以組合使用籍救,如果是num介于1和4之間,使用find({num:{$lt:4,$gt:1}})可以返回結(jié)果:

[ { _id: 55f65ff1ae0f94286cdabf19, num: 2 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 } ]

更多操作符請參看:http://docs.mongodb.org/manual/reference/operator/

2.3.3 限制顯示條數(shù)和配需

find()的一個參數(shù)是一個json對象渠抹,主要用于查詢條件蝙昙;第二個參數(shù)也是一個json對象,用于顯示限制及排序:limit屬性可以限制返回的條數(shù),設(shè)置find({},{limit:2})第一個參數(shù)為{}表示查詢所有)梧却,查看返回結(jié)果:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 0 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 } ]

排序:按照num進行降序排列:
find({},{limt:2,sort:[['num','desc']]}) (注意 是兩層的[]奇颠,因為你還能更具需要做不同優(yōu)先級的排序),返回結(jié)果:

[ { _id: 55f65ff1ae0f94286cdabf1b, num: 4 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 } ]

2.4 更新數(shù)據(jù):

2.4.1 更新單條數(shù)據(jù)

collection.update()方法可以用來更新數(shù)據(jù)放航,修改db.open()為以下代碼:

db.open(function(err,conn){
    
     //選擇集合`myCollection`
    db.collection('myCollection',function(err, collection){
        
       // 更新集合中所有的文檔
        collection.update({num:2}, {num:10}, {safe: true},function(err){
            if(err){
                console.log(err);
            }else{
                console.log('Successfully update');
            }

            //查看集合中的內(nèi)容
            collection.find().toArray(function(err,result){
                console.log(result);
                db.close({});
            });
        });
    });
});

返回結(jié)果:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 0 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]

從上面的例子可以看出update()接受四個參數(shù):

  1. 更新條件: { num:2 }表示更新num為2的記錄烈拒,這里也可以使用find()中的高級操作符,例如{num:{$lt:3}}更新num小于3的記錄:
[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 1 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10},
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]

但是奇怪的事情發(fā)生了,num:1 不是也小于3嗎荆几,為何不更新吓妆?因為update() 一次只能更新一條,所以會先去更新num:0吨铸,如果你現(xiàn)在用Ctrl+C停止服務(wù)后再執(zhí)行npm start 返回的結(jié)果才為你預(yù)想的那樣:

[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10},
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 } ]
  1. 要做的修改:本例中將滿足條件的記錄改成num:10;
  2. 更新選項:{safe: true}表示設(shè)置安全模式行拢,這個應(yīng)該一直使用;{mult: true}允許更新更多文檔也是很常用的選項诞吱;
  3. 回調(diào)函數(shù):操作成功或者失敗后執(zhí)行的函數(shù)舟奠,在這里我們除了在終端輸出錯誤信息外,還使用collection.find()查看操作后的變化房维;

2.4.2 更新或者插入

在更新選項對象中設(shè)置{upsert:true}沼瘫,upsert 既是 update + insert ,如果查詢的該條記錄存在那么就是update咙俩,如果不存在就insert一條符合條件的數(shù)據(jù)晕鹊。我們來試一試,修改上面的代碼:

//如果有的話將num:8修改為num:7 暴浦;如果沒有的話溅话,就插入一條num:7
 collection.update({num:8}, {num:7}, {safe: true,upsert:true},function(err){
            if(err){
                console.log(err);
            }else{
                console.log('Successfully update');
            }

            collection.find().toArray(function(err,result){
                console.log(result);
                db.close({});
            });
  });

發(fā)現(xiàn)返回的結(jié)果中多了一條num:7的數(shù)據(jù);

[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf1a, num: 3 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 },
  { _id: 55f6acd1cbd052390a8e6368, num: 7 } ]

2.4.3 為指定文檔添加字段和值

之前歌焦,都是在相應(yīng)的文檔中做原有字段的值的修改飞几,如果需要添加新的字段怎么辦?
可以用$set独撇,代碼如下:

 collection.update({num:3}, {$set:{desc:'favorite number'}}, {safe: true,upsert:true},function(err){
            if(err){
                console.log(err);
            }else{
                console.log('Successfully update');
            }

            collection.find().toArray(function(err,result){
                console.log(result);

                db.close({});
            });

        });

返回結(jié)果

[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf1b, num: 4 },
  { _id: 55f6acd1cbd052390a8e6368, num: 7 },
  { _id: 55f65ff1ae0f94286cdabf1a,
    num: 3,
    desc: 'favorite number' } ]

可以看出屑墨,我們update() 的第二個參數(shù)中使用了{$set:{desc:'favorite number'}為num: 3 這條數(shù)據(jù)添加了desc字段,并且值為:favorite number

2.4.4 查找并修改

2.5 刪除數(shù)據(jù)

2.5.1 移除文檔(行)

remove()可以移除整行的數(shù)據(jù)纷铣,修改之前的代碼:

    db.collection('myCollection',function(err, collection){
        // 刪除集合中num=4的文檔
        collection.remove({num: 4},function(err){
           if(err){
               console.log(err);
           }else{
               console.log("Successfully removed");
           }
           collection.find().toArray(function(err,result){
               console.log(result);
               db.close({});
           });
        });
    });

返回結(jié)果卵史,可以看出 num: 4的文檔被成功刪除:

Successfully removed
[ { _id: 55f65ff1ae0f94286cdabf17, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf18, num: 10 },
  { _id: 55f65ff1ae0f94286cdabf19, num: 10 },
  { _id: 55f6acd1cbd052390a8e6368, num: 7 },
  { _id: 55f65ff1ae0f94286cdabf1a,
    num: 3,
    desc: 'favorite number' } ]

如果將刪除條件{num: 4}改成{num:10}的會產(chǎn)生怎么樣的效果呢?
我們看返回的結(jié)果:

Successfully removed
[ { _id: 55f6acd1cbd052390a8e6368, num: 7 },
  { _id: 55f65ff1ae0f94286cdabf1a,
    num: 3,
    desc: 'favorite number' } ]

所有num:10的文檔統(tǒng)統(tǒng)被刪除了搜立。因此以躯,我們應(yīng)當特別注意:
remove()是一次性針對所有滿足條件的數(shù)據(jù)做操作

2.5.2 刪除數(shù)據(jù)集合(表)

使用dropCollection()可以刪除指定的集合;

db.open(function(err,conn){
    db.dropCollection('myCollection',function(err, result){
        if(err){
            console.log(err);
        }else{
            console.log(result);
        }
        db.close();

    });
});

返回

true

一定要慎重啄踊!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末忧设,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子颠通,更是在濱河造成了極大的恐慌址晕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顿锰,死亡現(xiàn)場離奇詭異谨垃,居然都是意外死亡启搂,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門刘陶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狐血,“玉大人,你說我怎么就攤上這事易核⌒僦” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵牡直,是天一觀的道長缀匕。 經(jīng)常有香客問我,道長碰逸,這世上最難降的妖魔是什么乡小? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮饵史,結(jié)果婚禮上满钟,老公的妹妹穿的比我還像新娘。我一直安慰自己胳喷,他們只是感情好湃番,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吭露,像睡著了一般吠撮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上讲竿,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天泥兰,我揣著相機與錄音,去河邊找鬼题禀。 笑死鞋诗,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的迈嘹。 我是一名探鬼主播削彬,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼江锨!你這毒婦竟也來了吃警?” 一聲冷哼從身側(cè)響起糕篇,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤啄育,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拌消,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挑豌,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡安券,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了氓英。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侯勉。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖铝阐,靈堂內(nèi)的尸體忽然破棺而出址貌,到底是詐尸還是另有隱情,我是刑警寧澤徘键,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布练对,位于F島的核電站,受9級特大地震影響吹害,放射性物質(zhì)發(fā)生泄漏螟凭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一它呀、第九天 我趴在偏房一處隱蔽的房頂上張望螺男。 院中可真熱鬧,春花似錦纵穿、人聲如沸下隧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汪拥。三九已至,卻和暖如春篙耗,著一層夾襖步出監(jiān)牢的瞬間迫筑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工宗弯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留脯燃,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓蒙保,卻偏偏與公主長得像辕棚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子邓厕,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

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