Я использовал учебник здесь , чтобы создать приложение, которое действует как служба, которая будет использоваться другими приложениями для взаимодействия с экземпляром MongoDB.Это руководство использует Mongoose и его концепцию модели для выполнения своей работы.Он также имеет статические входы и выходы для запроса и ответа, потому что ключи известны.Наконец, он не указывает имя коллекции.Однако мое требование состоит в том, чтобы сделать что-то действительно общее, с очень небольшими ограничениями.Я просто хочу что-то, что может быть вызвано для выполнения операций CRUD на экземпляре MongoDB с 4 или 5 маршрутами - по одному на каждую операцию CRUD, а затем, возможно, маршрут GET для получения спецификаций API, чтобы разработчики могли видетькаковы необходимые входные данные.Также хотелось бы, чтобы сам запрос указывал коллекцию и имя БД.Я сделал это самостоятельно, но потом у меня было так много проблем с Mongoose и его ограничительным характером, что я решил попробовать использовать для этого встроенный драйвер MongoDB.Я действительно не хочу начинать с нуля, так как считаю, что это должно быть довольно просто.У меня возникли трудности с тем, что Mongoose "магически" знает, как использовать соединение с БД, открытое в app.js, но когда я заменяю MongoClient на mongoose, вызовы MongoClient, которые я выполняю из service.ts, похоже, не имеютлюбой признак того, что постоянное соединение уже открыто и что-то не получается.Вот мой код:
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 и другие,но они почти такие же, как урок, и этот пост уже очень длинный):
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);
}
}
Я чувствую, что мне не хватает того, что нужно MongoClient, в чем нет необходимости при использовании Mongoose.Я искал несколько дней и не могу понять, что я делаю не так.Любая помощь будет принята с благодарностью.