转载:https://github.com/nswbmw/N-blog/blob/master/book/4.6%20%E8%BF%9E%E6%8E%A5%E6%95%B0%E6%8D%AE%E5%BA%93.md
早期我使用官方的 mongodb(也叫 node-mongodb-native)库,后来也陆续尝试使用了许多其他 mongodb 的驱动库,Mongoose 是比较优秀的一个,使用 Mongoose 的时间也比较长。比较这两者,各有优缺点。
优点:
缺点:
mongodb.open(function (err, db) {
if (err) {
return callback(err)
}
db.collection('users', function (err, collection) {
if (err) {
return callback(err)
}
collection.find({ name: 'xxx' }, function (err, users) {
if (err) {
return callback(err)
}
})
...
或者:
MongoClient.connect('mongodb://localhost:27017', function (err, mongodb) {
if (err) {
return callback(err)
}
mongodb.db('test').collection('users').find({ name: 'xxx' }, function (err, users) {
if (err) {
return callback(err)
}
})
...
现在支持 Promise 了,和 co 一起使用好很多。
优点:
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/test')
const BlogModel = mongoose.model('Blog', { title: String, content: String })
BlogModel.find()
缺点(个人观点):
schema.pre('save', function(next) {})
和 schema.post('find', function(next) {})
,只支持异步 next()
,灵活性大打折扣。Mongolass 保持了与 mongodb 一样的 api,又借鉴了许多 Mongoose 的优点,同时又保持了精简。
优点:
beforeXXX
和 afterXXX
(XXX为操作符首字母大写,如:afterFind
)函数实现,函数返回 yieldable 的对象即可,所以每个插件内可以做一些其他的 IO 操作。不同的插件顺序会有不同的结果,而且每个插件的输入输出都是 plain object,而非类 Mongoose 包装后的对象,没有虚拟属性,无需调用 toJSON 或 toObject。Mongolass 中的 .populate()
就是一个内置的插件。CastError: Cast to ObjectId failed for value "xxx" at path "_id"
只知道一个期望是 ObjectId 的字段传入了非期望的值,通常很难定位出错的代码,即使定位到也得不到错误现场。得益于 another-json-schema,使用 Mongolass 在查询或者更新时,某个字段不匹配它定义的 schema 时(还没落到 mongodb)会给出详细的错误信息,如下所示:const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User', {
name: { type: 'string' },
age: { type: 'number' }
})
User
.insertOne({ name: 'nswbmw', age: 'wrong age' })
.exec()
.then(console.log)
.catch(function (e) {
console.error(e)
console.error(e.stack)
})
/*
{ [Error: ($.age: "wrong age") ✖ (type: number)]
validator: 'type',
actual: 'wrong age',
expected: { type: 'number' },
path: '$.age',
schema: 'UserSchema',
model: 'User',
plugin: 'MongolassSchema',
type: 'beforeInsertOne',
args: [] }
Error: ($.age: "wrong age") ✖ (type: number)
at Model.insertOne (/Users/nswbmw/Desktop/mongolass-demo/node_modules/mongolass/lib/query.js:108:16)
at Object.<anonymous> (/Users/nswbmw/Desktop/mongolass-demo/app.js:10:4)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3
*/
可以看出,错误的原因是在 insertOne 一条用户数据到用户表的时候,age 期望是一个 number 类型的值,而我们传入的字符串 wrong age
,然后从错误栈中可以快速定位到是 app.js 第 10 行代码抛出的错。
缺点: