ES6最簡單的方式訪問MongoDB

weixin_34253539發表於2015-09-01

前言
MongoDB越來越流行,NodeJS也越來越流行,也許你第一時間用上了KOA框架,但是如何才能在KOA用ES6的方式訪問MongoDB呢?其實Github上不少類似的方案,比如你繼續使用mongoose的Promise方式運算元據庫,其實都沒什麼不可以。我的專案比較簡單,不想用太多複雜的框架,自己寫個Helper來連線資料庫好了。

程式碼其實很簡單,我貼出來,給官方驅動包個Promise殼兒,所有操作返回官方Promise,然後yield呼叫就這麼簡單

// helper_mongo.js檔案
// 作者freewolf
// 當然還是使用官方驅動
var MongoClient = require('mongodb').MongoClient;
var ObjectID = require('mongodb').ObjectID;

var mongoLink = ''; 
// 這裡修改成你的MongoLink字串mongodb://user:password@yourserver

// 插入方法
var insert = function(collectionName, obj) {
    return new Promise(function(resolve, reject) {
        MongoClient.connect(mongoLink, function(err, db) {
            if (err) reject(err);
            var collection = db.collection(collectionName);

            collection.insert(obj, {w: 1}, function(err, res) {
                db.close();
                if (err) reject(err);
                else resolve(res[0]);
            });
        });
    });
}
// 更新
var update = function(collectionName, obj) {
    return new Promise(function(resolve, reject) {
        MongoClient.connect(mongoLink, function(err, db) {
            if (err) reject(err);
            var collection = db.collection(collectionName);
            collection.update({_id: new ObjectID(obj._id)}, obj, {upsert: true,w: 1}, function(err, res) {
                db.close();
                if (err) reject(err);
                else resolve(res);
            });
        });
    });
}
// 查詢一個
var findOne = function (collectionName, query, option) {
    return new Promise(function(resolve, reject) {
        MongoClient.connect(mongoLink, function(err, db) {
            if (err) reject(err);

            var collection = db.collection(collectionName);

            if(option==undefined || option==null)
            {
                collection.findOne(query, function(err, res) {
                    db.close();
                    if (err) reject(err);
                    else resolve(res);
                });
            }else{
                collection.findOne(query, option, function(err, res) {
                    db.close();
                    if (err) reject(err);
                    else resolve(res);
                });
            }
        });
    });
}
// 查詢多個
var find = function(collectionName, query, option) {
    return new Promise(function(resolve, reject) {
        MongoClient.connect(mongoLink, function(err, db) {
            if (err) reject(err);

            var collection = db.collection(collectionName);
            if(option==undefined || option==null)
            {
                collection.find(query).toArray(function(err, res) {
                    db.close();
                    if (err) reject(err);
                    else resolve(res);
                });
            }else{
                collection.find(query, option).toArray(function(err, res) {
                    db.close();
                    if (err) reject(err);
                    else resolve(res);
                });
            }
        });
    });
}
// 刪除
var remove = function(collectionName, query) {
    return new Promise(function(resolve, reject) {
        MongoClient.connect(mongoLink, function(err, db) {
            if (err) reject(err);
            var collection = db.collection(collectionName);

            collection.remove(query, {w: 1}, function(err, res) {
                db.close();
                if (err) reject(err);
                else resolve(res);
            });
        });
    });
}
// 計數
var count = function(collectionName, query, option) {
    return new Promise(function(resolve, reject) {
        MongoClient.connect(mongoLink, function(err, db) {
            if (err) reject(err);
            var collection = db.collection(collectionName);
            if(query==undefined || query==null)
                query = {};
            if(option==undefined || option==null)
            {
                collection.count(query, function(err, count) {
                    db.close();
                    if (err) reject(err);
                    else resolve(count);
                });
            }else{
                collection.count(query, option, function(err, count) {
                    db.close();
                    if (err) reject(err);
                    else resolve(count);
                });
            }
        });
    });
}

module.exports.insert = insert;
module.exports.update = update;
module.exports.findOne = findOne;
module.exports.find = find;
module.exports.remove = remove;
module.exports.count = count;

好了 Helper結束
怎麼使用呢?
使用一個Service來裝飾一下

// service.js檔案
var ObjectID = require('mongodb').ObjectID;
var helperMongo = require('./helper_mongo');

module.exports = {
    // 建立
    insert : function * (obj){
        var res = yield helperMongo.insert(this.collectionName, obj);
        return res;
    },

    // 更新
    update : function * (obj){
        var res = yield helperMongo.update(this.collectionName, obj);
        return res;
    },

    // 刪除
    remove : function * (id){
        var res = yield helperMongo.remove(this.collectionName, { _id : new ObjectID(id) });
        return res;
    },


    // 查詢
    find : function * (query, option){
        var res = yield helperMongo.find(this.collectionName, query, option);
        return res;
    },

    // 查詢
    findOne : function * (query, option){
        var res = yield helperMongo.findOne(this.collectionName, query, option);
        return res;
    },

    // 取全部
    getAll : function * (){
        var res = yield helperMongo.find(this.collectionName, {});
        return res;
    },

    // 按照id查詢
    getById : function * (id){
        var res = yield helperMongo.findOne(this.collectionName, { _id : new ObjectID(id) });
        return res;
    },

    // 按照很多id來查詢
    getByIds :function * (ids, option){
        ids = ids.map(function(id) { return new ObjectID(id); });
        var res = yield helperMongo.find(this.collectionName, {_id: {$in: ids}}, option);
        return res;
    },

    // 列出(帶分頁)
    getByPage : function*(query, sort, pageSize, pageNum){
        if(!query)
            query = {};
        if(!sort)
            sort = [['_id', 'desc']];
        var option = {
            sort : sort,
            limit: pageSize,
            skip : (pageNum - 1) * pageSize
        };
        var res = yield helperMongo.find(this.collectionName, query, option);
        return res;
    },

    // 計數
    count : function * (query){
        if(!query)
            query = {};
        var res = yield helperMongo.count(this.collectionName, query);
        return res;
    }
}

然後呢?
其實更簡單 單例的操作從service繼承

// service_user.js舉例
var service = require('./service');
var helperMongo = require('../helper_mongo');
var ObjectID = require('mongodb').ObjectID;

var Service = function(){
    this.collectionName = 'users';

    // 這裡擴充你自己的方法 比如 按照邀請碼搜尋
    this.getByInviteCode = function * (inviteCode){
        var res = yield this.findOne({ invitecode : inviteCode });
        return res;
    }

    if(Service.instance == null)
    {
        Service.instance = this;
    }
    return Service.instance;
}
Service.prototype = service;

module.exports = Service;

好了 再看如何使用

var co = require('co');
var ServiceUser = require('./service_user.js');
var serviceUser = new ServiceUser();
// 其實可以直接返回單例例項在service_user.js 但是WS不能出提示 還是這樣吧

// Demo下
co(function*(){
    var user = {name:'freewolf', password:'123', invitecode:'abcd'};
    // 插入
    yield serviceUser.insert(user); 
    
    // 查詢 使用service包裝的方法
    var user1 = yield serviceUser.find({name:'freewolf'});
    // 查詢 使用擴充套件方法
    var user2 = yield serviceUser.getByInviteCode('abcd');
    // 分頁
    var sort = [['lastedittime', 'desc']];
    var pageSize = 20;  // 每頁20條
    var pageNum = 1;    // 第一頁
    var users = yield serviceUser.getByPage({}, sort, pageSize, pageNum);
    // ......
});

就寫這麼多吧,這個玩意就是官方驅動包個殼,很好用,滿足一般的需求。其實JS我並不太擅長,有什麼語法怪怪的地方,歡迎大家拍磚~

相關文章