我已使用教程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不需要的东西。我已经研究了几天,似乎无法找出我做错了什么。任何帮助将不胜感激。