# MogoDB Reference https://www.youtube.com/watch?v=ExcRbA7fy_A&list=PL4cUxeGkcC9h77dJ-QJlwGlZlTd4ecZOA # Introduction (No related Database) ![](https://hackmd.io/_uploads/r19WQRuMp.png) - Collections (similar to tables) - Documents (similar to records) ## Documents ![](https://hackmd.io/_uploads/ryClrAOz6.png) A document is the data, similar to a JSON file. It can include other documents, creating relationships between them # Installing MongoDB Download MongoDB https://www.mongodb.com/try/download/community ![](https://hackmd.io/_uploads/HkLwLROz6.png) ![](https://hackmd.io/_uploads/H1FtU0OMp.png) ![](https://hackmd.io/_uploads/S1h58Adzp.png) ## Mongo DM compass (GUI) ![](https://hackmd.io/_uploads/ryjev0dGT.png) ## MongoDB Shell (CLI) ![](https://hackmd.io/_uploads/rkQvdR_fT.png) ![](https://hackmd.io/_uploads/B1cRuCdG6.png) # Collection & Document Database can have many collection e.g. User collection, Post collection, Comment - Collection ![](https://hackmd.io/_uploads/HJ0X9AOzp.png) - Document ![](https://hackmd.io/_uploads/HkVD9Cdzp.png) Documents appear as JSON object, but actually, the date is store as BSON (binary json) ![](https://hackmd.io/_uploads/SkqRebtG6.png) ## Nest Document ![](https://hackmd.io/_uploads/HJnubbYzT.png) # MongoDB compass ## Connecting to MongoDB ### Local DataBase ![](https://hackmd.io/_uploads/ryKmXbFfT.png) ![](https://hackmd.io/_uploads/ryuBmWYfp.png) ### start_LOG /local->start_log ![](https://hackmd.io/_uploads/H1jL4WFza.png) Every time we start the DB, this action will be recording in the log file. ## Create Database ![](https://hackmd.io/_uploads/S1ocBbFG6.png) ![](https://hackmd.io/_uploads/HJmxuWYMp.png) ![](https://hackmd.io/_uploads/ByiOL-YMa.png) ## Adding a document ![](https://hackmd.io/_uploads/B1JMvWFf6.png) ![](https://hackmd.io/_uploads/SkczvZtfp.png) ![](https://hackmd.io/_uploads/SycytbFGp.png) A document can be represent as a JOSN object When we want insert multiple documents, you can use an array [] to insert them. ```json { "gunname": "AK-47", "owner": "firearmlover", "price": 1200, "tags": [ "rifle", "firearms" ], "rating": 8 }, { "gunname": "Glock 19", "owner": "gunenthusiast", "price": 600, "tags": [ "handgun", "guns" ], "rating": 9 }, { "gunname": "Remington 870", "owner": "shootingpro", "price": 800, "tags": [ "shotgun", "firearms" ], "rating": 7.5 } ] ``` ![](https://hackmd.io/_uploads/BJ-8ibYMa.png) ## Filter ![](https://hackmd.io/_uploads/r1PWnWKMp.png) # MongoDB shell Fetch Create Delete Update ``` PS C:\Users\USER> mongosh Current Mongosh Log ID: 653b909bfcab94a7cf4c6659 Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.10.6 Using MongoDB: 6.0.7 Using Mongosh: 1.10.6 mongosh 2.0.2 is available for download: https://www.mongodb.com/try/download/shell For mongosh info see: https://docs.mongodb.com/mongodb-shell/ ------ The server generated these startup warnings when booting 2023-10-20T15:41:17.416+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted ------ ``` ### use {database} ``` test> show dbs admin 40.00 KiB config 108.00 KiB gunShops 72.00 KiB local 88.00 KiB test> ``` ``` test> use gunShops switched to db gunShops ``` ``` gunShops> use notExistsDB switched to db notExistsDB ``` If the database does not exists, it will switch to a non-existent DB. ### DB ``` gunShops> db gunShops ``` ### show collections ``` gunShops> show collections handgun ``` ### Variable ``` gunShops> var name = "meowhecker" gunShops> name meowhecker ``` # Adding New Documents ``` gunShops> db gunShops gunShops> db.handgun //database.collection gunShops.handgun ``` ## insertOne() Syntax ``` database.collection.insertOne("JSON file") ``` ``` { "gunname": "M4A1", "owner": "tacticalshooter", "price": 1500, "tags": [ "rifle", "firearms" ], "rating": 9 } ``` ``` gunShops> db.handgun.insertOne({"gunname": "M4A1","owner": "tacticalshooter","price": 1500,"tags": ["rifle","firearms"],"rating": 9}) { acknowledged: true, insertedId: ObjectId("653b985cfcab94a7cf4c665c") } ``` ![](https://hackmd.io/_uploads/ByXbtzKGT.png) ## Inset document to non exists Collections ``` gunShops> db.admin.insertOne({"name":"meowhecker","age":18}) { acknowledged: true, insertedId: ObjectId("653b9ab7fcab94a7cf4c665d") } ``` The monogoDB will automatic create the collection ![](https://hackmd.io/_uploads/Hyg4szFM6.png) ![](https://hackmd.io/_uploads/B1s4sfFMT.png) ## insertMany() db -> current use database ```json db.collectionName.insertMany([{"key":"value"},{"key":"value"}]) ``` ![](https://hackmd.io/_uploads/rk98AQifa.png) # Finding Documents find -> query ``` gunShops> db.handgun.find() ``` find method -> only show the 20 document, if want to show more have to type "it" to iterate it ![](https://hackmd.io/_uploads/SkPv1VizT.png) ## Filter find(parameter 1,parameter 2,......) parameter -> filter ``` gunShops> db.handgun.find({"owner":"meowhecker"}) [ { _id: ObjectId("653b88c40aaa5623dde125b9"), gunname: 'P90', owner: 'meowhecker', price: 900, tags: [ 'handgub', 'guns' ], rating: 7 } ] ``` ### Multi-condition ``` gunShops> db.handgun.find({"rating": 9,"price":600}) [ { _id: ObjectId("653b8b400aaa5623dde125bc"), gunname: 'Glock 19', owner: 'gunenthusiast', price: 600, tags: [ 'handgun', 'guns' ], rating: 9 } ] ``` ``` db.handgun.find({"rating": 9},{"gunname":1,"price":1}) ``` ![](https://hackmd.io/_uploads/Byed7EsMT.png) ``` gunShops> db.handgun.find({},{"gunname":1,"price":1}) ``` ![](https://hackmd.io/_uploads/HJA2E4iGT.png) ## find single document by the object ID ``` db.handgun.find({_id:ObjectId("653b8b400aaa5623dde125bc")}) ``` ![](https://hackmd.io/_uploads/rkHFwNsMT.png) # Sorting & Limiting Data ## Count ``` gunShops> db.handgun.find({}).count() 5 ``` ## Limit ![](https://hackmd.io/_uploads/SJtyGHoGp.png) ## Sort ``` db.handgun.find().sort({"price":1}) ``` ![](https://hackmd.io/_uploads/BJCCMBsMa.png) # Nested Documents ![](https://hackmd.io/_uploads/SJl2XSsM6.png) Insert ![](https://hackmd.io/_uploads/B1nI4SoM6.png) --- ![](https://hackmd.io/_uploads/Bk8Z4Hofp.png) Insert ![](https://hackmd.io/_uploads/Sy1_ESjf6.png) # Operators & complex queries ## query Operators ### great then ($gt ``` db.handgun.find({"rating":{$gt:8}}) ``` ![](https://hackmd.io/_uploads/ByqpHBsf6.png) ### less then ($lt ``` db.handgun.find({"rating":{$lt:8}}) ``` ![](https://hackmd.io/_uploads/rySSISjfa.png) ### grate/less equal ($lte ``` db.handgun.find({"rating":{$lte:8}}) ``` ![](https://hackmd.io/_uploads/S1WaLSiz6.png) ## or Operator ($or) or -> multi-condition we have to use Array to do filter match ``` db.handgun.find({$or:[{"rating":8},{"owner":"meowhecker"}]}) ``` ![](https://hackmd.io/_uploads/S1NdYSofp.png) ## And Operator ($and ``` gunShops> db.handgun.find({$and:[{"rating":{$gte:8}},{"price":{$lte:1000}}]}) ``` ![](https://hackmd.io/_uploads/BJN35HjG6.png) ## Using $in and $nin ``` gunShops> db.handgun.find({"rating":{$in:[7,9]}}) ``` ![](https://hackmd.io/_uploads/S1bT7LjMa.png) ``` gunShops> db.handgun.find({"rating":{$nin:[7,9]}}) ``` ![](https://hackmd.io/_uploads/HkLeVLsGT.png) ## $where Match document satisfy the javascript expression Syntax: ``` $where:javascript Expression ``` ``` gunShops> db.handgun.find({$where:function(){return this.price === 1200}}) [ { _id: ObjectId("653b8b400aaa5623dde125bb"), gunname: 'AK-47', owner: 'firearmlover', price: 1200, tags: [ 'rifle', 'firearms' ], rating: 8 } ] ``` ### Null byte Null byte -> "%00" ```javascript db.admin.find({$where:function(){ return this.username === "meowhecker" && this.password === "meowmeow" }}) ``` db.admin.find({$where:function(){return this.username === "meowhecker" && this.password === "meowmeow"}}) ![](https://hackmd.io/_uploads/S1Vkty0GT.png) Using a Null byte to ignore the character after it (But it appears to work in old mongodb version) ``` gunShops> db.admin.find({ $where: function () {return this.username === 'meowhecker'\u0000' && this.password === 'meowmeow';}}) Uncaught: SyntaxError: Invalid Unicode escape. (1:74) > 1 | db.admin.find({ $where: function () {return this.username === 'meowhecker'\u0000' && this.password === 'meowmeow';}}) | ^ 2 ``` ### $ne "We can attempt to inject '$ne' into the password field to bypass authentication. ``` gunShops> db.admin.find({"username":"meowhecker","password":{$ne:"hacker"}}) [ { _id: ObjectId("653b9ab7fcab94a7cf4c665d"), name: 'meowhecker', age: 18, password: 'meowmeow', superadmin: 1, username: 'meowhecker' } ] ``` # Querying Array ``` gunShops> db.handgun.find({tags:"rifle"}) ``` ![](https://hackmd.io/_uploads/S1FsBUof6.png) ## Restrict Match ``` gunShops> db.handgun.find({tags:["rifle","firearms"]}) ``` ## $all ![](https://hackmd.io/_uploads/r19HtUoG6.png) ![](https://hackmd.io/_uploads/HJy_KIsG6.png) ## Retrieve sub document ![](https://hackmd.io/_uploads/r13Dq8iza.png) ![](https://hackmd.io/_uploads/BkBY9Uofa.png) # Delete Document ## deleteOne ![](https://hackmd.io/_uploads/HJhEoLszp.png) ``` gunShops> db.handgun.deleteOne({_id: ObjectId("653b985cfcab94a7cf4c665c")}) { acknowledged: true, deletedCount: 1 } ``` ![](https://hackmd.io/_uploads/SknMhUsMp.png) ## deleteMany()' # Update Document # $set ![](https://hackmd.io/_uploads/Bk_-pIjGT.png) ``` gunShops> db.admin.updateOne({ "name": "meowhecker"}, { $set: { "username": "meowhecker", "password": "meowmeow", "superadmin": 1 } }) { acknowledged: true, insertedId: null, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 } ``` ``` gunShops> db.admin.find() [ { _id: ObjectId("653b9ab7fcab94a7cf4c665d"), name: 'meowhecker', age: 18, password: 'meowmeow', superadmin: 1, username: 'meowhecker' } ] ``` ## MongoDB drivers Application(python,node)<--> MongoDB Drivers <--> MongoDB ![](https://hackmd.io/_uploads/r1rPkDsfp.png) ## Node ``` npm init ``` ![](https://hackmd.io/_uploads/BJ0Kgwif6.png) ``` touch app npm install express --save ``` Testing ```javascript const express = require('express') const app = express() app.listen(3000,()=>{ console.log("meowhecker") }) app.get('/gunshop',(req,res)=>{ res.json({"message":"gun shop api"}) }) ``` ``` nodemon app ``` ![](https://hackmd.io/_uploads/Sy9WmwsfT.png) ## install mongoDB in node js ``` npm install mongodb --save ``` # Connect to MongoDB db.js ```javascript const { MongoClient } = require('mongodb') let dbConnection module.exports = { connectToDb: (cb) => { MongoClient.connect('mongodb://localhost:27017/gunShop') .then(client => { dbConnection = client.db() return cb() }) .catch(err => { console.log(err) return cb(err) }) }, getDb: () => dbConnection } ``` app.js ```javascript const express = require('express') const app = express() //import DB const {connectToDB,getDB} = require('./db') //Connect to DataBase let db connectToDB((err)=>{ if (!err){ app.listen(3000,()=>{ console.log("meowhecker") }) mongoDB = getDB() } }) app.get('/gunshop',(req,res)=>{ res.json({"message":"gun shop api"}) }) ``` ![](https://hackmd.io/_uploads/Hy_t-tsGT.png) # Cursors & fetching Data ## app.js ```javascript const express = require('express') const app = express() //import DB const {connectToDB,getDB} = require('./db') //Connect to DataBase let mongoDB connectToDB((err)=>{ if (!err){ app.listen(3000,()=>{ console.log("meowhecker") }) mongoDB = getDB() // mongoDB = db(gunShop) } }) app.get('/gunshop',(req,res)=>{ let guns=[] // Find method will return a cursors . we have to use ForeEach to enumrate them(property) mongoDB.collection('handgun') .find() .sort({price:1}) .forEach(gun => { guns.push(gun) }).then(()=>{ res.status(200).json(guns) }).catch(()=>{ res.status(500).json({error:"Could not to fetch documents"}) }) //res.json({"message":"gun shop api"}) }) ``` ![](https://hackmd.io/_uploads/Syw9OFjGp.png) # Finding single Document ```javascript app.get('/gunshops/:id', (req, res) => { console.log(req.params.id); const objectId = new ObjectId(req.params.id); // 轉換為有效的 ObjectId mongoDB.collection('handgun') .find({ _id: objectId }) .toArray() // cursors to Arrat .then((guns) => { res.status(200).json(guns); }) .catch(() => { res.status(500).json({ "error": "Could not fetch the data" }); }); }); ``` ![](https://hackmd.io/_uploads/BkKjb9ofT.png) Invalid Document ID ![](https://hackmd.io/_uploads/BkIwGqizp.png) ```javascript app.get('/gunshops/:id', (req, res) => { if(ObjectId.isValid(req.params.id)){ console.log(req.params.id); const objectId = new ObjectId(req.params.id); mongoDB.collection('handgun') .find({ _id: objectId }) .toArray() .then((guns) => { res.status(200).json(guns); }) .catch(() => { res.status(500).json({ "error": "Could not fetch the data" }); }); }else { res.status(500).json({"error":"could not found the doc"}) } }); ``` ![](https://hackmd.io/_uploads/SJGQQciMT.png) # Login Authentication ```javascript //Hard Code Database const users = [ { username: 'user1', password: 'password1' }, { username: 'user2', password: 'password2' }, ]; // Using body Parse to Parse the pose request app.use(bodyParser.urlencoded({extended:true})) app.use(bodyParser.json()) //Middle SoftWare const authenticateUser = (req,res,next)=>{ const {username,password} = req.body console.log(username,password) const user = users.find(u=>u.username === username && u.password===password) console.log(user) if (user){ next(); }else{ res.status(401).json({error:"Authentication failed"}) } } //loging EndPing app.post("/login",authenticateUser, (req,res)=>{ console.log(1) res.status(200).json({Messages:"Authntication successful"}) }) ``` ![](https://hackmd.io/_uploads/Syb0W0pGp.png) Post Request ``` POST /login HTTP/1.1 Host: 127.0.0.1:3000 content-type:application/json Connection: keep alive Content-Length: 55 { "username": "user1", "password": "password1" } ``` ![](https://hackmd.io/_uploads/r13c-0pMp.png)