MongoDB without Mongoose
Tags: mongodb, node, javascript, webdev
Published: 2020-09-12 00:00:00

---
title: MongoDB without Mongoose
date: '2020-09-12'
og:
  description: 'How to create document in mongodb? How to update document in mongodb? How to delete data in mongodb? How to find from mongodb? Mongodb without mongoose'
  image: 'https://kamalhossain.me/assets/img/og/mongodb-without-mongoose.png'
  blognum: '#4'
author:
  twitter: 'kamalhossain_me'
  name: 'Kamal Hossain'
---

Lets suppose you just want to store a bunch of email addresses as your subscribers in your MongoDB database. Nothing else.

There is no need to implement an entire driver to handle this. Yes, of course, drivers provide many advantages to make our lives easy. But to keep things simple and lightweight we can use only MongoDB for CRUD operation without a mongoose.

What about validation? Don't worry, packages like [sanitize-html](https://www.npmjs.com/package/sanitize-html) can be used in MongoDB to validate data before storing to a database.

> Get the [Source code](https://github.com/kamal-hossain/blog-4-mongodb-without-mongoose) if you don't want to follow along.

Let's get started.

---

### Create a nodejs Server

Run the followings in your terminal:

```bash
mkdir mongodb-without-mongoose && cd mongodb-without-mongoose
```

These will create a folder called `mongodb-without-mongoose` and navigate to the folder.

```bash
npm init -y && npm install express mongodb --save
```

To initialize package.json file in our source folder to install dependencies, we run the first part of the command. And the second part is for installing the `express.js` and `MongoDB` as our dependencies.

Now let's create an `app.js` file in your project folder. And fill the file with the followings to create a simple server:

```js
const express = require('express')
const mongodb = require('mongodb')

const app = express()
let db

const PORT = 5000

app.get('/testRoute', (req, res) => res.end('Hello from Server!'))

app.listen(PORT, () => {
  console.log(`Node.js App running on port ${PORT}...`)
})
```

To start the server run:

```bash
node app.js
```

Here we have just created a simple server at port 5000. On `localhost:5000/testRoute` it will send the response, **Hello from Server!**.

---

### Connect to mongodb from server

In this example, we are going to connect the local MongoDB of windows. We are not going to any cloud services of MongoDB. So let's add some lines in our `app.js` to establish the connection.

```js
// ...
const app = express()
let db

let connectionString = `mongodb://localhost:27017/crud`
```

This is the default connection string of windows to connect to the local database. Now let us connect to MongoDB by using this string.

```js
// ...
const app = express()
let db

let connectionString = `mongodb://localhost:27017/crud`

mongodb.connect(
  connectionString,
  { useNewUrlParser: true, useUnifiedTopology: true },
  function (err, client) {
    db = client.db()
    app.listen(5000)
  }
)
```

Here above the MongoDB.connect() taking the connection string as the first argument, after that a second argument is an object for not getting the **deprecation warnings** from MongoDB.
And finally, the last argument is the callback function which can be used after MongoDB.connect() function trying to connect to MongoDB.

In our case, we are storing the database in a variable for further use and also started the app for listening in port 5000.

Now that we have our database connected, let's create some endpoints to make the app useful.

```js
// ...

mongodb.connect(
  connectionString,
  { useNewUrlParser: true, useUnifiedTopology: true },
  function (err, client) {
    db = client.db()
    app.listen(5000)
  }
)

app.post('/create-data', function (req, res) {
  // Sending request to create a data
  db.collection('data').insertOne({ text: req.body.text }, function (
    err,
    info
  ) {
    res.json(info.ops[0])
  })
})
```

Here we have set up a post request to our app to `/create-data`. Here we are using the `db.collection()` to specify the collection name in the _crud_ database that we have connected already.

In this method, we are chaining the `insertOne()` to create a document in the collection. We are passing two arguments in this function.

The first one is the **text** property with the string from the **req.body** object. And the second one is the callback function to do some stuff when the `insetOne()` method tries to insert the document to the collection.

In our callback function, we have two arguments, **err** and **info**. We are going to retrieve our collection of documents from `info.ops[0]` and then simply send back the response to the requested user.

Let's try a post request on `localhost:5000/create-data` with the following json data from [postman](https://www.postman.com/).

```json
{
  "text": "Kamal Hossain"
}
```

What have got?

Well, I have got a `500 Internal Server Error` with a bunch of HTML values in response. So let's check the console where is server is running.

**TypeError: Cannot read property 'text' of undefined**

I have got some lines in our console and the first line is telling this above. So why this is happening?

Well, we have sent JSON data to our nodejs app, where the server was created with the help of express.js. So by default, it can't read any JSON Object from incoming requests. So we have to add a line for that.

```js
// ...

mongodb.connect(
  connectionString,
  { useNewUrlParser: true, useUnifiedTopology: true },
  function (err, client) {
    db = client.db()
    app.listen(5000)
  }
)

app.use(express.json())
```

This will take care of the current problem. Let's save & restart our server. Then send the request again.

```json
{
  "text": "Kamal Hossain",
  "_id": "5f5c27353c14cc09309d4440"
}
```
This is the response I have got from our server. Which was sent from the `insertOne()` methods callback function. The _id is the unique id to identify our this particular document across the database.

Now that we have created our first document lets create a route to get all the documents from our collection via get request.

```js
// ...

app.post('/create-data', function (req, res) {
  // Sending request to create a data
  db.collection('data').insertOne({ text: req.body.text }, function (
    err,
    info
  ) {
    res.json(info.ops[0])
  })
})

app.get('/', function (req, res) {
  // getting all the data
  db.collection('data')
    .find()
    .toArray(function (err, items) {
      res.send(items)
    })
})
```

Here we are setting the route as `/` which will be the root route of any domain. In our case the localhost:5000. Here we are using the `find()` method to get all the documents from the collection. Lastly, we are chaining the `toArray()` method to put all the documents in an array, and in the callback of `toArray()` we are sending the response back. 

Lets do a get request in [postman](https://www.postman.com/) to `localhost:5000/`

```json
[
    {
        "_id": "5f5c27353c14cc09309d4440",
        "text": "Kamal Hossain"
    }
]
```

Now let's add two more routes in our app to update and delete a document.

```js
// ...

app.get('/', function (req, res) {
  // getting all the data
  db.collection('data')
    .find()
    .toArray(function (err, items) {
      res.send(items)
    })
})

app.put('/update-data', function (req, res) {
  // updating a data by it's ID and new value
  db.collection('data').findOneAndUpdate(
    { _id: new mongodb.ObjectId(req.body.id) },
    { $set: { text: req.body.text } },
    function () {
      res.send('Success updated!')
    }
  )
})
```

In our `/update-data` route are are mainly updating a document by `findOneAndUpdate()`. In this method we are passing the object Id that needs to be updated, then we are passing the updated text. And lastly, we are just sending the success response.

Let's now delete a document.

```js
// ...

app.put('/update-data', function (req, res) {
  // updating a data by it's ID and new value
  db.collection('data').findOneAndUpdate(
    { _id: new mongodb.ObjectId(req.body.id) },
    { $set: { text: req.body.text } },
    function () {
      res.send('Success updated!')
    }
  )
})

app.delete('/delete-data', function (req, res) {
  // deleting a data by it's ID
  db.collection('data').deleteOne(
    { _id: new mongodb.ObjectId(req.body.id) },
    function () {
      res.send('Successfully deleted!')
    }
  )
})
```

In our `delete-data` route we are using `delete()` method to delete the document from collection. And lastly sending a response to the client in the callback function.

---
Originally published at https://kamalhossain.me/blog/mongodb-without-mongoose