281 lines
6.6 KiB
Markdown
281 lines
6.6 KiB
Markdown
Drivers
|
|
|
|
- In order to interact with mongodb instead of mongosh or mongodb compass, but in order to interact with application code like node, python,etc we need mongodb drivers for the programming languages as it gives the specific language bindings.
|
|
These drivers allows us to communicate with mongodb on programatically level.
|
|
|
|
db,js
|
|
```js
|
|
const { MongoClient } = require("mongodb");
|
|
|
|
let dbConnection;
|
|
|
|
// the callback function will be called after it connect to the database
|
|
const connectToDb = (cb) => {
|
|
// format : protocol://server:PORT/databasename
|
|
MongoClient.connect("mongodb://localhost:27017/new2")
|
|
.then((client) => {
|
|
dbConnection = client.db();
|
|
return cb();
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
return cb(err);
|
|
});
|
|
};
|
|
|
|
module.exports = {
|
|
connectToDb,
|
|
getDb: () => dbConnection,
|
|
};
|
|
```
|
|
|
|
or
|
|
db.js
|
|
```js
|
|
import { MongoClient } from "mongodb";
|
|
|
|
const connectToDb = async () => {
|
|
try {
|
|
const client = await MongoClient.connect("mongodb://localhost:27017/new2");
|
|
const dbConnection = client.db();
|
|
return { dbConnection };
|
|
} catch (err) {
|
|
return { err };
|
|
}
|
|
};
|
|
|
|
export { connectToDb };
|
|
|
|
```
|
|
|
|
handler.js
|
|
```js
|
|
import { connectToDb } from "../_lib/db";
|
|
|
|
async function Fn(){
|
|
|
|
const { dbConnection, err } = await connectToDb();
|
|
|
|
if (err) {
|
|
console.log("cant connect to db");
|
|
return new Response("error", { status: 500 });
|
|
}
|
|
const commentsCursor = dbConnection
|
|
.collection("comments")
|
|
.find({ text: filteredCommentsRegex });
|
|
const filteredComments = await commentsCursor.toArray();
|
|
}
|
|
|
|
```
|
|
|
|
- Cursors
|
|
When we use find method it returns the cursor which points to the set of documents. But in order to get results we need to use cursor methods too like `toArray` and `forEach`. When using shell, shell does that automatically but when coding we have to do things manually. By deafult we can get first 20 documents in shell. for more use the `it` command to get more 20 results.
|
|
https://www.mongodb.com/docs/drivers/node/v4.1/fundamentals/crud/read-operations/cursor/
|
|
|
|
app.js
|
|
```js
|
|
const express = require("express");
|
|
const { connectToDb, getDb } = require("./db");
|
|
const PORT = process.env.PORT || 8080;
|
|
|
|
// init app and middleware
|
|
const app = express();
|
|
|
|
// db connection
|
|
let db;
|
|
|
|
connectToDb((err) => {
|
|
if (!err) {
|
|
app.listen(PORT, () => {
|
|
console.log("app is listening in PORT ", PORT);
|
|
});
|
|
db = getDb();
|
|
}
|
|
});
|
|
|
|
// routes
|
|
app.get("/books", (req, res) => {
|
|
let books = [];
|
|
|
|
// same as db.books
|
|
db.collection("books")
|
|
.find()
|
|
.sort({ author: 1 })
|
|
.forEach((book) => books.push(book))
|
|
.then(() => {
|
|
res.status(200).json(books);
|
|
})
|
|
.catch(() => {
|
|
res.status(500).json({ error: "Could not fetch the book" });
|
|
});
|
|
// res.json({ msg: "welcome to the api" });
|
|
});
|
|
```
|
|
|
|
other ways are
|
|
```js
|
|
const collection = db.collection("books");
|
|
const cursor = collection.find({});
|
|
|
|
// using for await of
|
|
console.log("async");
|
|
for await (const doc of cursor) {
|
|
console.log(doc);
|
|
}
|
|
|
|
// or using toArray
|
|
const collection = db.collection("books");
|
|
const cursor = collection.find({});
|
|
console.log("async");
|
|
|
|
const docArray = await cursor.toArray();
|
|
console.log(docArray);
|
|
|
|
|
|
```
|
|
|
|
|
|
#### Finding single document
|
|
```js
|
|
app.get("/books/:id", (req, res) => {
|
|
const { id } = req.params;
|
|
|
|
// if id is not valid then return 400(bad request)
|
|
if (!ObjectId.isValid(id)) {
|
|
console.log("Wrong id format");
|
|
res.status(400).json({ error: "Not a valid doc id" });
|
|
return;
|
|
}
|
|
|
|
db.collection("books")
|
|
// as this is not the normal integer or string id so we need to import ObjectId from mongodb module
|
|
.findOne({ _id: new ObjectId(id) })
|
|
.then((doc) => {
|
|
// if doc is null means no such document is found with the given id
|
|
if (!doc) {
|
|
res.status(404).json("Not found");
|
|
return;
|
|
}
|
|
res.status(200).json(doc);
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).json("Could not fetch the document");
|
|
});
|
|
});
|
|
```
|
|
|
|
**Creating document**
|
|
```js
|
|
// post request
|
|
app.post("/books", (req, res) => {
|
|
const book = req.body;
|
|
|
|
db.collection("books")
|
|
.insertOne(book)
|
|
.then((result) => {
|
|
res.status(201).json(result);
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).json({ err: "Couldn't create a new account" });
|
|
});
|
|
});
|
|
```
|
|
|
|
**Deleting document**
|
|
```js
|
|
// delete book by id
|
|
app.delete("/books/:id", (req, res) => {
|
|
const { id } = req.params;
|
|
|
|
if (ObjectId.isValid(id)) {
|
|
db.collection("books")
|
|
.deleteOne({ _id: new ObjectId(id) })
|
|
.then((result) => {
|
|
res.status(200).json(result);
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).json({ error: "Could not delete the document" });
|
|
});
|
|
} else {
|
|
res.status(400).json({ error: "not a valid document id" });
|
|
}
|
|
});
|
|
|
|
```
|
|
|
|
**Updating document**
|
|
```js
|
|
// update book by id
|
|
app.patch("/books/:id", (req, res) => {
|
|
const updates = req.body;
|
|
|
|
const { id } = req.params;
|
|
|
|
if (ObjectId.isValid(id)) {
|
|
// as $set operator expects something like {title : 'title1', author : 'author1' }
|
|
// and body is already in form of the object so directly passing body
|
|
db.collection("books")
|
|
.updateOne({ _id: new ObjectId(id) }, { $set: updates })
|
|
.then((result) => {
|
|
res.status(200).json(result);
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).json({ error: "Could not update document" });
|
|
});
|
|
} else {
|
|
res.status(400).json({ error: "Not a valid doc id" });
|
|
}
|
|
});
|
|
|
|
|
|
```
|
|
|
|
|
|
### Pagination
|
|
when we get results then it can contain like 1000s of documents so its important to limit it too. so here query parameter is useful.
|
|
```js
|
|
// get all books
|
|
app.get("/books", async (req, res) => {
|
|
// if there is no parameter named 'p' specfied
|
|
// then it is assigned as 0
|
|
const page = req.query.p || 0;
|
|
// maximum books can be 3 in one page
|
|
const booksPerPage = 3;
|
|
|
|
let books = [];
|
|
|
|
// same as db.books
|
|
db.collection("books")
|
|
.find()
|
|
.sort({ author: 1 })
|
|
.skip(booksPerPage * page)
|
|
.limit(booksPerPage)
|
|
.forEach((book) => books.push(book))
|
|
.then(() => {
|
|
res.status(200).json(books);
|
|
})
|
|
.catch(() => {
|
|
res.status(500).json({ error: "Could not fetch the book" });
|
|
});
|
|
// res.json({ msg: "welcome to the api" });
|
|
// books = await db.collection("books").find().toArray();
|
|
// console.log("books: ", books);
|
|
//
|
|
|
|
// const collection = db.collection("books");
|
|
// const cursor = collection.find({});
|
|
// console.log("async");
|
|
//
|
|
// const docArray = await cursor.toArray();
|
|
// console.log(docArray);
|
|
|
|
//for await (const doc of cursor) {
|
|
//console.log(doc);
|
|
//}
|
|
});
|
|
```
|
|
|
|
|
|
|
|
|
|
|