您的位置:首页 > 数据库 > Mongodb

NodeJS 与 MongoDB 的邂逅

2014-05-07 16:27 113 查看
虽然 NodeJS 的模块和开发资源相当多,但相关文件却非常不足或是不完整,多半文献都只着重于基础的使用和片断的说明,如果不去看源代码,使用 NodeJS 来完成实用的网站,会有很大的困难度。对于已经有过 Web 开发经验的人,转换使用 NodeJS 不免也需要花一番功夫,过去经验中许多的常用的功能,都仍要一一花大量时间尝试才得以解决。而这样的情况,对于开发者来说相当的糟,也是很多人重新再评估是否使用 NodeJS 的重点因素之一。有道是”一人得道,鸡犬升天”,因此笔者未来将尝试将自己的实际经验,写成一篇篇重点功能实现的文章和随
Copy 即用的范例,减少其他人浪费同样的时间再摸索。

开发一个 Web 应用程序,最重要的莫过于数据库的使用,过去 PHP 有 MySQL 当最佳伙伴,而现在 NodeJS 有 MongoDB 做最佳的组合。MongoDB 是 NoSQL 的代表之一,其采用 JSON/BSON 当做数据储存和沟通的格式,亦使用 JavaScript 做为 Server-side 的执行程序语言(相当于传统 RDBMS 的预储程序),一切设计和习惯与 NodeJS 搭配使用起来,简直绝配。若你对 MongoDB 的一些基本操作有疑问,可以先参考旧文”MongoDB 快速笔记”。

使用 MongoDB

MongoDB 拥有 NoSQL 的普遍特色,不用预先定义 Schema,所有的 database 和 collection(相当于传统 RDBMS 的 Table),都会在新增数据后,自动被建立,我们只要专注于使用 NodeJS 操作数据库即可。

要在 NodeJS 里使用 MongoDB,可以安装 mongodb native driver,若透过 npm 来安装:

npm install mongodb


然后可以使用 NodeJS 建立 MongoDB connection pool ,做一些基础的操作:

var mongodb = require('mongodb');

var mongodbServer = new mongodb.Server('localhost', 27017, { auto_reconnect: true, poolSize: 10 });
var db = new mongodb.Db('mydb', mongodbServer);

/* open db */
db.open(function() {
/* Select 'contact' collection */
db.collection('contact', function(err, collection) {
/* Insert a data */
collection.insert({
name: 'Fred Chien',
email: 'cfsghost@gmail.com',
tel: [
'0926xxx5xx',
'0912xx11xx'
]
}, function(err, data) {
if (data) {
console.log('Successfully Insert');
} else {
console.log('Failed to Insert');
}
});

/* Querying */
collection.find({ name: 'Fred Chien' }, function(err, data) {
/* Found this People */
if (data) {
console.log('Name: ' + data.name + ', email: ' + data.email);
} else {
console.log('Cannot found');
}
});
});
});


注:这是 MongoDB 的基本常识,每当新增一笔数据,MongoDB 会自动帮该笔数据加上 _id 字段,并给与一个唯一值(格式是 ObjectId),所以我们不需要像过去 使用 SQL Server 一般,自己刻意去定义一个 ID 字段。

预设的 ObjectId 范围太小,改用 UUID 来当数据的唯一 ID

如果你过去有过 Web 开发经验,到这边肯定会开始有一些疑问欲求解,第一个问题肯定是”ObjectId 的数量极限?”。笔者在此不会回答这问题,因为这答案并不重要,想要准确知道答案,可以去”

mongodb.org“寻找答案。

比起上述问题,相信你应该更想问:

预设的 ObjectId 适用的范围?
如果日后数据库要扩展(Scale),是否有其他的 ID 解决方案可使用?


一般情况, MongoDB 预设的 ObjectId 就相当够用了,但如果你是要建构大型的 Web Service 或是保留未来的扩充性,可使用 UUID 去代替 ObjectId。不过,因为 MongoDB 本身并不生成 UUID,若是要使用 UUID,就必需先自行产生好 UUID,然后在新增数据时指定生成好的 UUID 给 _id 字段,让 MongoDB 改用我们给的 ID 而不使用预设生成的 ObjectId。

因为要自行产生 UUID,必需先为 NodeJS 安装模块 node-uuid:

npm install uuid


然后生成 UUID 并在 insert 时使用:

var uuid = require('node-uuid');
var mongodb = require('mongodb');

var mongodbServer = new mongodb.Server('localhost', 27017, { auto_reconnect: true, poolSize: 10 });
var db = new mongodb.Db('mydb', mongodbServer);

/* open db */
db.open(function() {
/* Select 'contact' collection */
db.collection('contact', function(err, collection) {

/* Generate UUID(16 Bytes) and convert to BinaryData object for mongodb */
var uuidBinary = new Buffer(uuid.v1({}, []));
var id = mongodb.BSONPure.Binary(uuidBinary, mongodb.BSONPure.Binary.SUBTYPE_UUID);

/* Insert a data with uuid */
collection.insert({
_id: id,
name: 'Fred Chien',
email: 'cfsghost@gmail.com'
}, function(err, data) {
if (data) {
console.log('Successfully Insert');
} else {
console.log('Failed to Insert');
}
});
});
});


你可能会发现,在上面的范例程序中,我们将 UUID 转成 MongoDB BSON 的 BinaryData 格式,这是为了效能考虑,因为用纯字符串当做 Unique ID,在数据库搜寻上会比 BinaryData Object 慢很多。

储存时间戳(Timestamp)

关于储存时间的问题,如果你去各大 MongoDB 讨论区询问或查询,通常大家都会告诉你不必做这件事,因为每一笔数据被建立后,自动产生的 ObjectId 就包含了建立的时间讯息,我们只要去学习如何从中去解析时间即可。但是,不单只是建立时间,有时我们会为数据加上各种不同的时间戳,如:更新时间等,所以,储存时间戳还是必要的。

虽然网络上相关 NodeJS 范例并不多,但 MongoDB 确实有 Timestamp 的数据结构可以用,我们可以这样使用:

var uuid = require('node-uuid');
var mongodb = require('mongodb');

var mongodbServer = new mongodb.Server('localhost', 27017, { auto_reconnect: true, poolSize: 10 });
var db = new mongodb.Db('mydb', mongodbServer);

/* open db */
db.open(function() {
/* Select 'contact' collection */
db.collection('contact', function(err, collection) {

/* Generate Timestamp and convert for mongodb */
var ts = new Date().getTime();
var i = ts % 1000;
var t = new mongodb.BSONPure.Timestamp(i, Math.floor(ts * 0.001));

/* Insert a data with uuid */
collection.insert({
name: 'Fred Chien',
email: 'cfsghost@gmail.com',
created: t
}, function(err, data) {
if (data) {
console.log('Successfully Insert');
} else {
console.log('Failed to Insert');
}
});
});
});


建立数据库索引(Index)

过去有接触过数据库的人应该都很清楚,索引(Index)是能优化数据查询速度的重要功能,MongoDB 同样也有索引的设计。

可以在 NodeJS 中,这样为 name 字段加上索引:

collection.createIndex({ name: 1 });


后记
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: