本文基於MongoDB
的Node.JS
驅動實現MongoDB
基本的增刪改查操作。驅動官方文件見:mongodb.github.io/node-mongod…。
1 插入文件
MongoDB
中Collection
類的insertOne
和insertMany
方法用來插入文件。
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URl
const url = 'mongodb://localhost:27017';
// Database name
const dbName = 'myproject';
const client = new MongoClient(url);
(async function() {
try {
await client.connect();
console.log('connected correctly to server');
const db = client.db(dbName);
// Insert a single document
let r = await db.collection('inserts').insertOne({a: 1});
assert.equal(1, r.insertedCount);
// Insert multiple documents
r = await db.collection('inserts').insertMany([{a: 2}, {a: 3}]);
assert.equal(2, r.insertedCount);
// Close connection
client.close();
} catch(err) {
console.log(err.stack);
}
})();
複製程式碼
第一個insert
語句向inserts
集合中插入單個文件,注意在MongoDB
中無需顯示的建立集合inserts
,MongoDB
服務會在首次插入文件時自動建立該集合。
insertOne
和insertMany
方法接收第二個引數options
,可以配置寫關注
、函式序列化
等引數,具體引數列表見:mongodb.github.io/node-mongod…。
例如下面這段程式碼會將傳入的函式序列化並寫入到副本集replica set
:
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URL
const url = 'mongodb://localhost:27017';
// Database name
const dbName = 'myproject';
const client = new MongoClient(url);
(async function() {
try {
await client.connect();
console.log('connected correctly to server');
const db = client.db(dbName);
// Insert a single document
const r = await db.collection('inserts').insertOne({
a: 1,
b: function () {return 'hello';}
}, {
w: 'majority',
wtimeout: 10000,
serializeFunctions: true,
forceServerObjectId: true
});
assert.equal(1, r.insertedCount);
client.close();
} catch(err) {
console.log(err.stack);
}
})();
複製程式碼
2 更新文件
Collection
類的updateOne
和updateMany
方法用於實現更新操作。
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URL
const url = 'mongodb://localhost:27017';
// Database name
const dbName = 'myproject';
const client = new MongoClient(url);
(async function () {
try {
await client.connect();
console.log("Connected correctly to server");
const db = client.db(dbName);
// Get the updates collection
const col = db.collection('updates');
// Insert some documents
let r = await col.insertMany([{a: 1}, {a: 2}, {a: 2}]);
assert.equal(3, r.insertedCount);
// Update a single document
r = await col.updateOne({a: 1}, {$set: {b: 1}});
assert.equal(1, r.matchedCount);
assert.equal(1, r.modifiedCount);
// Update multiple documents
r = await col.updateMany({a: 2}, {$set: {b: 2}});
assert.equal(2, r.matchedCount);
assert.equal(2, r.modifiedCount);
// Upsert a single document
r = await col.updateOne({a: 3}, {$set: {b: 3}});
assert.equal(0, r.matchedCount);
assert.equal(1, r.upsertedCount);
// Close connection
client.close();
} catch(err) {
console.log(err.stack);
}
})();
複製程式碼
updateOne
和updateMany
方法接收第三個引數options
,可以用來配置寫關注
、更新並插入
等引數,具體引數列表見:mongodb.github.io/node-mongod…。
3 刪除文件
Collection
類的deleteOne
和deleteMany
方法可以用來刪除文件。
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URL
const url = 'mongodb://localhost:27017';
// Database name
const dbName = 'myproject';
const client = new MongoClient(url);
(async function () {
try {
await client.connect();
console.log("Connected correctly to server");
const db = client.db(dbName);
// Get the collection to remove
const col = db.collection('removes');
// Insert some documents
let r = await col.insertMany([{a: 1}, {a: 2}, {a: 2}]);
assert.equal(3, r.insertedCount);
// Remove a single document
r = await col.deleteOne({a: 1});
assert.equal(1, r.deletedCount);
// Remove multiple documents
r = await col.deleteMany({a: 2});
assert.equal(2, r.deletedCount);
// Close connection
client.close();
} catch(err) {
console.log(err.stack);
}
})();
複製程式碼
deleteOne
和deleteMany
方法可以接收第二個引數options
,用來配置寫關注
等引數,具體引數列表見:mongodb.github.io/node-mongod…。
4 查詢文件
查詢MongoDB
的主要方法是find
方法。find
方法返回一個用來運算元據的遊標
。下面的程式碼限制查詢個數為2條文件,並使用toArray
方法匯出文件。
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URL
const url = 'mongodb://localhost:27017';
// Database name
const dbName = 'myproject';
const client = new MongoClient(url);
(async function () {
try {
await client.connect();
console.log("Connected correctly to server");
const db = client.db(dbName);
// Get the collection
const col = db.collection('find');
// Insert some documents
const r = await col.insertMany([{a: 1}, {a: 1}, {a: 1}]);
assert.equal(3, r.insertedCount);
// Get first two documents that match the query
const docs = await col.find({a: 1}).limit(2).toArray();
assert.equal(2, docs.length);
// Close connection
client.close();
} catch(err) {
console.log(err.stack);
}
})();
複製程式碼
方法find
返回的遊標
支援各種鏈式呼叫,具體支援的方法見:mongodb.github.io/node-mongod…。
例如下面的程式碼使用遊標
的next
方法進行迭代:
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URL
const url = 'mongodb://localhost:27017';
// Database name
const dbName = 'myproject';
const client = new MongoClient(url);
(async function () {
try {
await client.connect();
console.log("Connected correctly to server");
const db = client.db(dbName);
// Get the collection
const col = db.collection('find');
// Insert some documents
const r = col.insertMany([{a: 1}, {a: 1}, {a: 1}]);
assert.equal(3, r.insertedCount);
// Get the cursor
const cursor = col.find({a: 1}).limit(2);
// Iterate over the cursor
while(await cursor.hasNext()) {
const doc = cursor.next();
console.dir(doc);
}
// Close connection
client.close();
} catch(err) {
console.log(err.stack);
}
})();
複製程式碼
下面的程式碼使用遊標
的each
方法進行迭代:
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URL
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'myproject';
const client = new MongoClient(url);
(async function () {
try {
await client.connect();
console.log("Connected correctly to server");
const db = client.db(dbName);
const col = db.collection('find');
const r = await col.insertMany([{a:1}, {a:1}, {a:1}]);
assert.equal(3, r.insertedCount);
col.find({a: 1}).limit(2).each((err, doc) => {
if (doc) {
console.dir(doc);
} else {
client.close();
return false;
}
});
} catch(err) {
console.log(err.stack);
}
})();
複製程式碼
5 投影
預設情況下,查詢會返回文件的所有欄位,可以通過投影(projection)
來限制MongoDB
服務返回的欄位。投影配置文件
用來控制返回包含
哪些欄位、不包含
哪些欄位:
{ field1: <value>, field2: <value> ... }
複製程式碼
<value>
為0
或false
表示不包含,1
或true
表示包含。_id
欄位預設返回,無需配置。除了_id
欄位外,其他所有欄位的配置不可以同時出現0
和1
。下面的例子僅返回age
欄位:
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
// Connection URL
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'myproject';
const client = new MongoClient(url);
(async function () {
try {
await client.connect();
console.log("Connected correctly to server");
const db = client.db(dbName);
const col = db.collection('project');
let r = await col.insertMany([{name: 'Jim', age: 18}, {name: 'Lucy', age: 16}]);
assert.equal(2, r.insertedCount);
r = await col.find({name: 'Jim'}).project({age: 1, _id: 0}).toArray();
console.log(r);
// Close connection
client.close();
} catch (err) {
console.log(err.stack);
}
})();
複製程式碼