NodeJS / Express:将Mongoose代码转换为本机MongoDB代码

时间:2018-09-21 16:45:00

标签: node.js express mongoose node-mongodb-native

我已使用教程here创建了一个应用程序,该应用程序将用作其他应用程序与MongoDB实例进行交互的服务。本教程使用猫鼬及其模型概念进行工作。由于密钥是已知的,因此它也具有用于请求和响应的静态输入和输出。最后,它没有指定集合名称。但是,我的要求是制作几乎没有约束的真正通用的东西。我只想要一种可以称为传递的功能,以对MongoDB实例执行CRUD操作,具有4或5条路由-每个CRUD操作一条,然后是GET路由以获取API规范,以便开发人员可以看到所需的输入是什么。我还希望请求本身指定集合和数据库名称。我自己完成了此工作,但随后在Mongoose及其限制性性质方面遇到了很多问题,以至于我选择尝试使用本机MongoDB驱动程序来执行此操作。我真的不想从头开始,因为我觉得这应该很简单。我遇到的困难是Mongoose“神奇地”知道使用app.js中打开的数据库连接,但是当我用MongoClient代替mongoose时,我从service.ts进行的MongoClient调用似乎没有任何持久连接已经打开并且一切都失败的线索。这是我的代码:

app.js:

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var cors = require('cors');
var app = express();

const MongoClient = require(`mongodb`).MongoClient;
const mongodb_uri = 'mongodb://127.0.0.1:27017/test';
var mongoose = require('mongoose');
var bluebird = require('bluebird');

var api = require('./routes/api.route')

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/api', api);

mongoose.Promise = bluebird
MongoClient.Promise = bluebird

// Open MongoDB Connection

//old from tutorial - works
//mongoose.connect('mongodb://127.0.0.1:27017/test', { useNewUrlParser: true, autoIndex: false })
//.then(()=> { console.log(`Succesfully connected to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`)})
//.catch(()=> { console.log(`Error connecting to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`)})

//this opens a connection, but the other modules can't seem to "see" it
MongoClient.connect(mongodb_uri, { useNewUrlParser: true })
.then(()=> { console.log(`Succesfully connected to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`)})
.catch((e)=> { console.log(`Error connecting to the MongoDb database at URL: mongodb://127.0.0.1:27017/test: ` + e)})

//I figured I could make this a variable and maybe the other modules would see it:
//const mongoConn = MongoClient.connect(mongodb_uri, { useNewUrlParser: true })
//.then(()=> { console.log(`Succesfully connected to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`)})
//.catch((e)=> { console.log(`Error connecting to the MongoDb database at URL: mongodb://127.0.0.1:27017/test: ` + e)})

//This was another method I was given, but it doesn't work either:
//let testConnection; // allows us to reuse the database connection once it is opened
/*const open_test_connection = async () => {
  try {
    client = await MongoClient.connect(mongodb_uri, { useNewUrlParser : true });
    console.log(`Succesfully connected to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`);
  } catch (err) {
    console.log(`Error connecting to the MongoDb database at URL: mongodb://127.0.0.1:27017/test`); 
    throw new Error(err); 
  }
  testConnection = client.db('test');
};*/

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
  next();
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

//this was me trying to add "mongoConn" to the exports to see if that might work
module.exports = app, mongoConn;

这是来自service.ts模块的一段代码,可以完成实际的工作(我可以提供controller.ts和其他代码,但是它们与本教程几乎相同,并且这篇文章已经很长了): / p>

exports.updateTestData = async function(update){
    var id = update._id

    // Check the existence of the query parameters, If they don't exist then assign a default value
    var dbName = update.dbName ? update.dbName : 'test'
    var collection = update.collection ? update.collection : 'testing'; 

    //old Mongoose way
    //const Test = mongoose.model(dbName, TestSchema, collection);

    try{
        //For some reason the tutorial wanted to find the doc before updating it
        //I plan to take this out
        //For now this is what I am testing with - note the use of "mongoConn" which I expect
        //to be available from app.js
        //Find the existing Test object by the Id
        var existingTestData = await mongoConn.collection(collection).findById(id);
        console.log(existingTestData)
    }catch(e){
        throw Error("Error occurred while finding the Test document - " + e)
    }

    // If no existing Test object exists return false
    if(!existingTestData){
        return false;
    }

    console.log("Existing document is " + existingTestData)

    //Old code from tutorial
    //existingTestData.title = update.title
    //existingTestData.description = update.description
    //existingTestData.status = update.status

    //I replaced it with this because I don't want static keys
    existingTestData = new Test(JSON.parse(JSON.stringify(update)));


    console.log("New data is " + existingTestData)

    try{
        //old tutorial method - save is being deprecated and I don't want findById anymore
        //so I am going to use findByIdAndUpdate instead - not again the "mongoConn" from app.js
        //var savedOutput = await existingTestData.save()
        var savedOutput = await mongoConn.findByIdAndUpdate(id, existingTestData, {new:true})
        return savedOutput;
    }catch(e){
        throw Error("An error occurred while updating the Test document - " + e);
    }
}

我觉得我在使用Mongoose时缺少了MongoClient不需要的东西。我已经研究了几天,似乎无法找出我做错了什么。任何帮助将不胜感激。

0 个答案:

没有答案