eolas/Databases/MongoDB/Introduction.md

157 lines
5.3 KiB
Markdown
Raw Normal View History

2022-08-06 14:00:04 +01:00
---
tags:
- Databases
- mongo_db
---
# MongoDB: Introduction
MongoDB is not a relational database system like SQL, instead it is document-based which means you do not neeed to design database tables and schema, you are simply storing data as JSON and there is no transformation of the data.
Most of the notes on Mongo will introduce it within the context of Node.js backend. We will be sending Javascript objects and arrays to Mongo and returning them as JSON.
2022-08-06 15:30:04 +01:00
## Setting-up a MongoDB database
2022-08-11 08:30:05 +01:00
First create a direc## Mongoose tory for the database and set permissions:
2022-08-06 15:30:04 +01:00
```bash
$ mkdir /data/db
$ sudo chown -R `id -un` /data/db
```
Then start the Mongo daemon
```bash
mongod
```
2022-08-08 15:00:04 +01:00
This will run continuously in the terminal and should say somewhere that it is waiting for connections on port `27017`. This command must be executed before you run any backend that interacts with the Mongo database.
2022-08-06 15:30:04 +01:00
### MongoDB Compass
2022-08-08 15:00:04 +01:00
_Compass_ is a graphical interface for viewing and interacting with the data in your Mongo database. It will automatically load to the default Mongo port: `27017`.
2022-08-06 15:30:04 +01:00
![](/img/mongo-compass.png)
### Arch Linux troublshooting
2022-08-08 15:00:04 +01:00
Most times any problems will be a result of a Mongo process that is already running. Resolve with:
```bash
# Kill running Mongo process...
# Identify PID
sudo lsof -iTCP -sTCP:LISTEN -n -P
sudo kill [pid]
```
Otherwise try the below.
2022-08-06 15:30:04 +01:00
```bash
# Check that the systemd service is runnign for Mongo
sudo systemctl status mongodb
# If not, enable and start service (only need to do this once for machine)
sudo systemctl enable --now mongodb
sudo systemctl start --now mongodb
# If issues with Mongo daemon...
# Remove the current socket
2022-08-08 15:00:04 +01:00
rm /tmp/mongodb-27017.sock
2022-08-06 15:30:04 +01:00
```
2022-08-11 08:30:05 +01:00
## MongoDB data hierarchy: databases, collections, documents
2022-08-08 15:00:04 +01:00
Although Mongo is not a relational database it has a structure that we can understand in relation to that paradigm. A **database** is obviously the overall structure. It comprises **collections** which are organised sets of data that are analagous to [tables](/Databases/Relational_database_architecture.md#table) in RDBs. Within each collection are a series of **documents** which we can think of as being equivalent to [rows](/Databases/Relational_database_architecture.md) in RDB table: units that comprise the collection.
2022-08-09 08:30:04 +01:00
A document is a container comprising key-value pairs in the manner of an object.
2022-08-06 14:00:04 +01:00
2022-08-11 08:30:05 +01:00
## Connecting to our database with Mongoose
2022-08-06 15:30:04 +01:00
Now that we have installed and configured MongoDB, we need to connect from it via Node.js.Mongoose is a simple API for interacting with a Mongo database via Node.
With this installed we can connect to a database. We don't have any Mongo databases yet beyond the defaults but the following Mongoose connection logic will create and connect to a new database called `playground`:
```js
mongoose
.connect("mongodb://127.0.0.1/playground")
.then(() => console.log("Connected to MongoDB"))
.catch((err) => console.error(err));
```
2022-08-11 08:30:05 +01:00
## Creating collections and documents
2022-08-08 15:00:04 +01:00
2022-08-09 08:30:04 +01:00
In order start adding collections and documents to our database, we use Mongoose's schema structure. (This is specific to the Mongoose wrapper and is not a structure that is a part of Mongo in general.)
We use a schema to define the shape of documents in a MongoDB collection. To do this we instantiate an instance of the Mongoose `Schema` class and set our properties:
2022-08-11 08:30:05 +01:00
### Creating a schema
2022-08-09 08:30:04 +01:00
```js
const courseSchema = new mongoose.Schema({
name: String,
author: String,
tags: [String],
data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
2022-08-11 08:00:04 +01:00
isPublished: Boolean
2022-08-09 08:30:04 +01:00
});
```
This is just like defining an interace or type within TypeScript.
#### Available data types
The following data types are available:
* `String`
* `Number`
* `Boolean`
* `Array`
* `Date`
* `Buffer`
* `ObjectID` (for UUIDs)
2022-08-11 08:30:05 +01:00
### Models
2022-08-09 08:30:04 +01:00
Once we have established our schema we can then create a **model** of it. A model is basically a class representation of the interface we define in the schema:
```js
const Course = mongoose.model("Course", courseSchema);
```
With this in place, we can then create instances of the model. This stands in relation to the model as an object does to a class:
```js
const course = new Course({
name: "Node.js Course",
author: "Ozzy Osbourne",
tags: ["node", "backend"],
2022-08-11 08:30:05 +01:00
isPublished: true
2022-08-09 08:30:04 +01:00
});
```
2022-08-11 08:00:04 +01:00
![](/img/mongoose-hierarchy.svg)
2022-08-11 08:30:05 +01:00
Having created a database, connected to it with Mongoose, and created a model we will see our collection reflected in Compass:
![](img/../../../img/mongo-collection.png)
### Adding a document
We have our database (`lllplayground`) and collection (`courses`) established. We now need to add documents to our collection. We will move our previous code into a function since this will be an asynchronous process:
```js
const nodeCourse = new Course({
name: "Node.js Course",
author: "Ozzy Osbourne",
tags: ["node", "backend"],
isPublished: true,
});
async function addCourseDocToDb(courseDocument) {
const result = await courseDocument.save();
console.log(result);
}
addCourseDocToDb(nodeCourse);
```
When we run this we have the Mongo document outputted to the console:
```
{
name: 'Python Course',
author: 'Terry Ogleton',
tags: [ 'node', 'backend' ],
isPublished: true,
_id: new ObjectId("62f4ac989d2fec2f01596b9b"),
date: 2022-08-11T07:15:36.978Z,
__v: 0
}
```