Using MongoDB
This page is part of the documentation for release V1.0. This documentation is outdated and V1.0 is no longer maintained. See index for the latest information.
The website uses MongoDB, a document-oriented database program, to fetch and serve information for the backend. When running in a development environment, the backend is automatically configured to connect to a public OSC testing database. This section documents the basic prolegomena of operating and managing the OSC Website database.
For the OSC testing URI, see here (note that the database is public and volatile, and not meant for production environments). For instructions on changing environments or configuring your own Mongo connection URI, see here.
Mongoose Basics
The project uses the Mongoose library as an abstraction over the default MongoDB NodeJS package. Mongoose organizes database structures into schemas and models (analogous to schemas in SQL) that automatically validate and enforce rules on database entries. For instance:
const mongoose = require('mongoose')
const ImageSchema = new mongoose.Schema({
filename: {
type: String,
required: true
},
description: {
type: String,
required: true
},
path: {
type: String,
required: true
},
date: {
type: Date,
required: true,
default: Date.now
}
})
const ImageModel = mongoose.model('image', ImageSchema)
module.exports = { ImageSchema, ImageModel }
In the source above, an ImageSchema
is defined. The schema defines filename, description, path, and date
as properties of the 'Image' object. Similarly, it enforces certain rules over these properties: that 'filename' is a required string, that 'date' is a required JavaScript 'Date' object with a default value, etc.
Furthermore, Mongoose allows us to formalize a 'model' from this schema, in this case, it is named ImageModel
. The ImageModel
acts as a driver to our database's 'Image' collection (collections are structures similar to tables in SQL). Once the model is created, it is exported and ready to be used in other files. What follows is a series of code examples drawn from the website sourcecode that illustrate what models are capable of:
Example 1
const images = await ImageModel.find().sort({ date: -1 })
The example above fetches all images in the database and sorts them in descending (-1) date order.
Example 2
const image = new ImageModel({
filename: req.file.filename,
description: req.body.Description,
path: req.file.path
})
image.save((err) => {
if (err) return res.status(500).send({ error: 'Internal Server Error' })
})
In the example above, a new instance of an ImageModel
with some given data, automatically validates it to make sure it matches the schema we've defined, and then attempts to save it to the database.
To learn more about Mongoose and MongoDB, refer to the Mongoose Documentation and the MongoDB NodeJS documentation.
Database.js
The database connection URI is configured in utils/config.js, whilst the effective database connection configuration happens in utils/database.js. The database utility modularizes the connection (allowing us to handle the connection in multiple files simultaneously), whilst also implementing various event listeners:
mongoose.connection.on('connected', () => {
// CONNECTION SUCCEEDED...
})
mongoose.connection.on('error', (error) => {
// CONNECTION FAILED...
})
mongoose.connection.on('disconnected', () => {
// DISCONNECTED...
})
process.on('SIGINT', (error, data) => {
// SIGINT: User stopped the program.
})
Database.js is imported, and a database connection is subsequently opened in main.js.
Setting up your own database
If you're interested in hosting your own instance of the website, you'll need to set up your own MongoDB node. The MongoDB team currently offers free (but limited) database hosting on their MongoDB Atlas platform. Alternatively, you can set up MongoDB community edition on your machine and host your own instance for "free."