There are two key components to make MongoDB accessible and serve as a server.
MongoClient
provided by themongodb
libs from MongoDB provider.Expressjs
as the server hosting.
Here is the basic workflow diagram of MongoDB access
Database connection
MongoClient
:
MongoClient.connect(mongoUri, {useNewUrlParser: true, useUnifiedTopology: true})
.catch(err => {
console.log(err);
process.exit(1);
})
.then(async db => {
await GedsyriaDb.DbAccess(db);
app.listen(serverPort, () => {console.log(`listen on port ${serverPort}`)})
});
DBAccess
:
After the connection succeeds, passing the DB entity into DBAccess
to find the suitable collection in the cluster:
static async DbAccess(conn) {
if (geoSyria) {
return
}
try {
geoSyria = conn.db(db).collection(collection);
} catch (e) {
console.error('Uable connect to Database...' + e.message);
}
}
Server host
Now using expressjs
to host the server; from the design, we are querying 3 types of data:
- general data - the Latitude and Longitude data strings help the frontend locate the right spot on the 3D globe.
- yearly data - the death counts and sorted list (sorting list from server side)
- detail data - the details information of the selected string (through
id
)
...
const app = express();
...
const apiQuery = new express.Router();
apiQuery.route('/').get(apiController.responseData);
apiQuery.route('/year').get(apiController.responseSumData);
apiQuery.route('/id').get(apiController.responseDetailData);
app.use('/api', apiQuery);
module.exports = app;
The typical middleware response function has three input/output pipe: request, response, next
,
if the request.query
has an id or year parameter, the response would trigger the conditional query to the database to get limited results.
static async responseSumData(req, res, next) {
console.log("responseSum_query: " + req.query)
try {
let response = await DbAccess.getSumData(req.query);
if (!response) {
res.status(404).json({api_error: 'Not found'});
return
}
return res.json(response);
} catch (e) {
console.error(`api server: ${e}`)
}
}
As the response conducts the MongoDB query language
arrayPipeline = [
{
$project: {
year: 1,
latitude: 1,
longitude: 1,
deaths_num: '$high'
}
}, {$sort: {deaths_num: -1}}, {$skip: 6}];
return await geoSyria.aggregate(arrayPipeline).toArray();
As a result, the front end will only get the specific data string relevant to the visualization's needs. And lots of calculations will be handled in the database directly, accelerating the interactive experiences.