2016,9.20mongodb與node.js的合作

1.安裝mongodb nodejs driver

要安裝mongodb nodejs的原生driver,可以通過(guò)npm,也可以通過(guò)github下載:

npm install mongodb

2連接到數(shù)據(jù)庫(kù)

var mongo = require('mongodb'),

Server = mongo.Server,

Db = mongo.Db;

var server = new Server('localhost', 27017, {auto_reconnect: true});

var db = new Db('foo', server);

db.open(function(err, db) {

if(!err) {

console.log("We are connected");

}

});

查詢Get

db.open(function(err, db) {

if(!err) {

console.log("We are connected");

db.collection('bar', function(err, collection){

collection.find().toArray(function(error, bars){console.log(bars);});

collection.find({a:1}).toArray(function(error, bars){console.log(bars);});

collection.findOne({a: 1}, function(error, bar){console.log(bar)});

});

}

});

這里一旦用find獲取到結(jié)果集之后,需要調(diào)用toArray方法,并傳遞回調(diào)函數(shù),這個(gè)時(shí)候才能拿到真正的數(shù)據(jù)。第二個(gè)find語(yǔ)句則是查找所有a=1的文檔。第三個(gè)find語(yǔ)句則是只找第一個(gè)滿足條件的文檔。具體更多的過(guò)濾條件可以參考官方的Query語(yǔ)句。這里有個(gè)有趣的事情需要注意,find本身并不執(zhí)行查詢,它只是返回一個(gè)Cursor實(shí)例,你可以遍歷這個(gè)Cursor來(lái)查詢數(shù)據(jù)。如下面的例子:

// Cursors don't run their queries until you actually attempt to retrieve data

// from them.

// Find returns a Cursor, which is Enumerable. You can iterate:

collection.find(function(err, cursor) {

cursor.each(function(err, item) {

if(item != null) console.dir(item);

});

});

// You can turn it into an array

collection.find(function(err, cursor) {

cursor.toArray(function(err, items) {

console.log("count: " + items.length);

});

});

插入Insert

db.open(function(err, db) {

if(!err) {

db.collection('bar', function(err, collection) {

var doc1 = {a: 1};

var doc2 = {a: 2, b: 'b2'};

var docs = [{a:3}, {a:4}];

collection.insert(doc1);

collection.insert(doc2, {safe:true}, function(err, result) {});

collection.insert(docs, {safe:true}, function(err, result) {});

});

}

});

第一個(gè)insert和第二個(gè)insert的區(qū)別在于,增加了一個(gè)option對(duì)象參數(shù)({safe:true})以及一個(gè)回調(diào)函數(shù)。MongoDB的

insert/update/remove都是異步的,也就是說(shuō)發(fā)出insert命令之后,就不管數(shù)據(jù)庫(kù)是否執(zhí)行成功了。要想知道數(shù)據(jù)庫(kù)是否執(zhí)行成功,需

要再發(fā)出一個(gè)查詢請(qǐng)求來(lái)獲取連接(Connection)的最后一個(gè)錯(cuò)誤狀態(tài)。為了簡(jiǎn)化這個(gè)過(guò)程,也就支持{safe:true}這個(gè)參數(shù),使得

insert和錯(cuò)誤狀態(tài)查詢能夠一起執(zhí)行,一旦設(shè)置這個(gè)參數(shù),一定要增加回調(diào)函數(shù)作為第三個(gè)參數(shù)。具體地,我們可以看下面地例子來(lái)理解這個(gè)

{safe:true}的意義:

db.collection('bar', function(err, collection){

collection.insert({a:996, _id:'1'}, function(error, bars){

console.log('insert success without safe');

console.log(error);

console.log(bars);

collection.insert({a:996, _id:'1'}, {safe:true}, function(error, bars){

console.log('insert fail with safe and get error');

console.log(error);

console.log(bars);

collection.insert({a:996, _id:'1'}, function(error, bars){

console.log('insert fail without safe but no error');

console.log(error);

console.log(bars);

});

});

});

});

# output result

[app.js] insert success without safe

[app.js] null

[app.js] [ { a: 996, _id: '1' } ]

[app.js] insert fail with safe and get error

[app.js] { [MongoError: E11000 duplicate key error index: foo.bar.$_id_? dup key: { : "1" }]

name: 'MongoError',

err: 'E11000 duplicate key error index: foo.bar.$_id_? dup key: { : "1" }',

code: 11000,

n: 0,

connectionId: 38,

ok: 1 }

[app.js] undefined

[app.js] insert fail without safe but no error

[app.js] null

[app.js] [ { a: 996, _id: '1' } ]

這里的_id是mongodb默認(rèn)的主鍵,是不允許重復(fù)的。如果你傳入了_id則以傳入的值作為主鍵,如果沒(méi)有傳入則會(huì)自動(dòng)生成。你可以看到,第一次insert,我們也不關(guān)心是不是真的插入了,幸運(yùn)的是真的成功了,因?yàn)椴淮嬖赺id為1的數(shù)據(jù)。第二次插入的時(shí)候,我們?cè)O(shè)置{safe:true}以確保一定插入成功,這是會(huì)報(bào)主鍵重復(fù)的錯(cuò)誤。第三次同樣的插入,但是不設(shè)置{safe:true},這個(gè)時(shí)候發(fā)現(xiàn)并沒(méi)有報(bào)錯(cuò),而且回調(diào)函數(shù)還拿到了要插入的數(shù)據(jù)。是不是第三次插入成功了呢?不是的,其實(shí)正像第二次插入的一樣,肯定是主鍵重復(fù)了,但是由于我們并沒(méi)有要求返回最后的錯(cuò)誤狀態(tài),所以mongodb drvier直接回調(diào)了我們傳入的回調(diào)函數(shù),并且設(shè)置error為null,bars為要插入的數(shù)據(jù)??偨Y(jié)一下,如果你要確保數(shù)據(jù)是否更新(insert/update/remove)成功必須要設(shè)置{safe:true}選項(xiàng)。

更新Update

collection.update({a:996}, {$push: {b:'b'}}, function(error, bars){});

collection.update({a:996}, {$set: {a:997}}, function(error, bars){});

注意,這里為了代碼簡(jiǎn)單,我們沒(méi)有設(shè)置{safe:true}。你可以看到update的第一個(gè)參數(shù)是條件,即對(duì)a=996的文檔進(jìn)行更新。第二個(gè)參數(shù)則

是表示要如何更新文檔,譬如第一個(gè)update是增加一個(gè)屬性b,且設(shè)置其值為字符串'b';第二個(gè)update是修改a的值為997??梢钥闯?,第二個(gè)

參數(shù)是一個(gè)對(duì)象,其屬性名是一個(gè)操作符,以$開(kāi)頭,值為一個(gè)對(duì)象。這些操作符除了這里的$push和$set,還有其它的$inc, $unset,

$pushAll等等,具體可以參考這里。

刪除Delete

collection.remove({a:997}, {safe:true}, function(error, count){

console.log(error);

console.log(count);

collection.remove();

});

這里第一個(gè)remove是刪除a=997的所有文檔?;卣{(diào)函數(shù)的第二個(gè)參數(shù)是表示相應(yīng)刪除的文檔數(shù)量。第二個(gè)remove則是刪除該collection中的所有文檔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容