重新封装了一下NODE-MONGO 使其成为一个独立的服务.可以直接通过get/post来操作

本文介绍了一种将Node与MongoDB操作封装成独立服务的方法,通过GET/POST请求即可进行数据库操作,包括查询、增删改等。服务内置日志记录功能,便于异常排查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# 重新封装了一下NODE-MONGO 使其成为一个独立的服务.可以直接通过get/post来操作
# consts.js 配置用的数据,用于全局参数配置
# log.js 自己写的一个简单的存储本地log的功能,数据库异常或者逻辑上产生异常数据的时候输出查错
# servicemongo.js 主服务程序,可以直接node servicemongo.js 启动,挂起端口服务
# routemongo.js 请求路由相关
# mongo.js 封装了一些基本的node对mongo操作
# 使用方法,直接node  servicemongo.js 就行,也可以在另一个项目里调用servicemongo的start 
# 注意 node包没传,缺什么自己安装什么吧,看下错误日志,缺什么就直接npm i XXX 装上就好

项目我打包上传到资源了(待审核状态,差不多明天就能下载了):

https://me.youkuaiyun.com/download/u013761036


consts.js

module.exports = {
    default: {
        defaultDataServicePort: 2323,//数据库服务接口端口
        defaultMongoUrl : 'mongodb://localhost:27017/',//Mongo数据库连接地址
    }
}

log.js

var fs = require('fs');
const sd = require('silly-datetime');

//输出log的时候,可以传过来一个key,来代表这个是谁输出的,建议是文件名字+函数名字 xxx.js-funxx
//consolelog('main.js-main', 'star-ok');
function consolelog(key, data) {
    try {
        if ('string' != typeof data) {
            data = JSON.stringify(data);
        }
        let formatData = sd.format(new Date(), 'YYYY-MM-DD HH:mm:ss') + '->' + key + '\n';
        formatData = formatData + data + '\n\n';
        // 创建一个可以写入的流,写入到文件 xxx-xx-xx.log 中,日期
        let outPutLogFilePath = "./" + sd.format(new Date(), 'YYYY-MM-DD') + ".log";
        var writerStream = fs.createWriteStream(outPutLogFilePath, { 'flags': 'a' });
        writerStream.write(formatData, 'UTF8');
        writerStream.end();
        writerStream.on('finish', function () {
            //console.log("写入完成。");
        });
        writerStream.on('error', function (err) {
            //console.log(err.stack);
        });
    } catch (e) {

    }
}
module.exports = {
    consolelog,
};

mongo.js

const url = require('url');
const { MongoClient, ObjectId } = require('mongodb');
const sd = require('silly-datetime');
const _ = require('lodash');
const { consolelog } = require('./log');
const config = require('./consts');
const { defaultMongoUrl: mongourl } = _.get(config, 'defaultMongoUrl', config.default);


const goError = (mongoLink, req, res, body = null) => {
    //数据库操作失败一定全都打log出来。
    const params = url.parse(req.url, true).query;
    let logMess = 'Mongo operation failed:' + JSON.stringify(params);
    if (body) {
        logMess = logMess + '\nBody:' + JSON.stringify(body);
    }
    consolelog('mongo.js-goError', logMess);
    if (mongoLink != null) {
        mongoLink.close();
    }
    res.end();
}

//查询数据,条件查询,但是不支持ObjectID,条件的格式是{"key":"value"}
const findMongo = (dbname, collection, where, req, res) => {
    MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, client) {
        //if (err) throw err;
        if (err) {
            return goError(client, req, res);
        }
        try {
            where = JSON.parse(where);
        } catch (e) {
            return goError(client, req, res);
        }
        const db = client.db(dbname);
        db.collection(collection).find(where).sort({ updateTime: -1 }).toArray(function (err, datas) {
            //if (err) throw err;
            if (err) {
                return goError(client, req, res);
            }
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf8" });
            res.end(JSON.stringify(datas));
            client.close();
        });
    });
    return;
}

//查询数据,value专门支持ObjectID类型,key可以是_id,也可以是别的
const findMongoByKOBJV = (dbname, collection, key, value, req, res) => {
    MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, client) {
        //if (err) throw err;
        if (err) {
            return goError(client, req, res);
        }
        const db = client.db(dbname);
        const were = {};
        try {
            were[key] = ObjectId(value);
        } catch (e) {
            return goError(client, req, res);
        }
        db.collection(collection).find(were).sort({ updateTime: -1 }).toArray(function (err, datas) {
            //if (err) throw err;
            if (err) {
                return goError(client, req, res);
            }
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf8" });
            res.end(JSON.stringify(datas));
            client.close();
        });
    });
    return;
}

//根据条件删除数据,不支持ObjectID类型
const deleteMongo = (dbname, collection, body, req, res) => {
    MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, client) {
        //if (err) throw err;
        if (err) {
            return goError(client, req, res, body);
        }
        const db = client.db(dbname);
        if (body.were == null) {//卡一下,防止出人命!
            return goError(client, req, res, body);
        }
        let were = null;
        try {
            were = JSON.parse(body.were);
        } catch (e) {
            return goError(client, req, res, body);
        }
        db.collection(collection).deleteMany(were, function (err, datas) {
            //if (err) throw err;
            if (err) {
                return goError(client, req, res, body);
            }
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf8" });
            //{"result":{"n":0,"ok":1},"connection":{"id":6,"host":"localhost","port":27017},"deletedCount":0,"n":0,"ok":1}
            res.end(JSON.stringify(datas));
            client.close();
        });
    });
    return;
}


const deleteMongoByKOBJV = (dbname, collection, body, req, res) => {

    MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, client) {
        //if (err) throw err;
        if (err) {
            return goError(client, req, res, body);
        }
        const db = client.db(dbname);
        let key = body.key;
        let value = body.value;
        if ((!key) || (!value)) {//卡一下,防止出人命!
            return goError(client, req, res, body);
        }
        let were = {};
        try {
            were[key] = ObjectId(value);
        } catch (e) {
            return goError(client, req, res, body);
        }

        db.collection(collection).deleteMany(were, function (err, datas) {
            //if (err) throw err;
            if (err) {
                return goError(client, req, res, body);
            }
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf8" });
            //{"result":{"n":0,"ok":1},"connection":{"id":4,"host":"localhost","port":27017},"deletedCount":0,"n":0,"ok":1}
            res.end(JSON.stringify(datas));
            client.close();
        });
    });
    return;
}

//插入一条数据
const insertMongo = (dbname, collection, body, req, res) => {
    MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, client) {
        //if (err) throw err;
        if (err) {
            return goError(client, req, res, body);
        }
        let db = client.db(dbname);
        //自动添加创建时间和修改时间
        body[0]['createdAt'] = new Date();
        body[0]['updatedAt'] = new Date();
        db.collection(collection).insertMany(body, function (err, datas) {
            //if (err) throw err;
            if (err) {
                return goError(client, req, res, body);
            }
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf8" });
            //{"result":{"ok":1,"n":1},"ops":[{"v1":"1111","v2":"2222","createdAt":"2019-11-05T08:07:37.087Z","updatedAt":"2019-11-05T08:07:37.087Z","_id":"5dc12dc99af00a30429a4b5c"}],"insertedCount":1,"insertedIds":{"0":"5dc12dc99af00a30429a4b5c"}}
            res.end(JSON.stringify(datas));
            client.close();
        });
    });
    return;
}


const updateById = (dbname, collection, body, req, res) => {

    MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, client) {
        //if (err) throw err;
        if (err) {
            return goError(client, req, res, body);
        }
        let db = client.db(dbname);
        let _id = null;
        let updata = null;
        try {
            _id = ObjectId(body.id);
            updata = JSON.parse(body.data);
            updata['updatedAt'] = new Date();
        } catch (e) {
            return goError(client, req, res, body);
        }
        let updateCmd = { $set: updata };
        db.collection(collection).updateOne({ _id }, updateCmd, function (err, datas) {
            //if (err) throw err;
            if (err) {
                return goError(client, req, res, body);
            }
            res.writeHead(200, { "Content-Type": "text/plain; charset=utf8" });
            //{"result":{"n":1,"nModified":1,"ok":1},"connection":{"id":2,"host":"localhost","port":27017},"modifiedCount":1,"upsertedId":null,"upsertedCount":0,"matchedCount":1,"n":1,"nModified":1,"ok":1}
            res.end(JSON.stringify(datas));
            client.close();
        });
    });
    return;
}

module.exports = {
    updateById,
    findMongoByKOBJV,
    deleteMongoByKOBJV,
    deleteMongo,
    findMongo,
    insertMongo
};



routemongo.js

const url = require('url');
const mongo = require('./mongo');
const querystring = require('querystring');
const { consolelog } = require('./log');

const workFind = async (req, res) => {
    const params = url.parse(req.url, true).query;
    switch (params.cmd) {
        case 'query': {
            mongo.findMongo(params.n, params.c, params.w, req, res);
        } break;
        case 'querykeyid': {
            mongo.findMongoByKOBJV(params.n, params.c, params.k, params.v, req, res);
        } break;
        default: {
            res.end();
        }; break;
    }
}

const workUpdate = async (req, res) => {
    const params = url.parse(req.url, true).query;
    let postdata = '';
    req.on('data', function (chunk) {
        postdata += chunk;
    });
    req.on('end', async function () {
        if (postdata == '') {//过滤掉这种,防止后面误操作破坏数据库数据
            return res.end();
        }
        let postdataobj = null;
        try {
            postdataobj = querystring.parse(postdata);
        } catch (e) {
            let logMess = 'Mongo operation failed:\n' + JSON.stringify(params) + '\npostdata:' + postdata
            consolelog('routemongo.js-workUpdate', logMess);
            return res.end();
        }
        try {
            switch (params.cmd) {
                case 'delete': {
                    mongo.deleteMongo(params.n, params.c, postdataobj, req, res);
                } break;
                case 'deletekeyid': {
                    mongo.deleteMongoByKOBJV(params.n, params.c, postdataobj, req, res);
                } break;
                case 'insert': {
                    const postdataobjarr = [postdataobj];
                    mongo.insertMongo(params.n, params.c, postdataobjarr, req, res);
                } break;
                case 'updatebyid': {
                    mongo.updateById(params.n, params.c, postdataobj, req, res);
                } break;
                default: {
                    res.end();
                }; break;
            }
        } catch (e) {
            datas = null;
        }
    });
}

module.exports = {
    workFind,
    workUpdate
};




servicemongo.js

const http = require('http');
var url = require("url");
const routemongo = require('./routemongo');
const config = require('./consts');
const { consolelog } = require('./log');
const _ = require('lodash');

const route = async (req, res) => {
    switch (url.parse(req.url).pathname) {
        case "/find": {//查
            routemongo.workFind(req, res);
        }; break;
        case "/update": {//增 删 改
            routemongo.workUpdate(req, res);
        }; break;
        default: {
            res.end();
        } break;
    }
}

const start = async () => {
    const { defaultDataServicePort } = _.get(config, 'defaultDataServicePort', config.default);
    consolelog('servicemongo.js-start', 'start:' + defaultDataServicePort);
    http.createServer(function (req, res) {
        route(req, res);
    }).listen(defaultDataServicePort);
};

module.exports = {
    start,
};

start();





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值