This commit is contained in:
nm1 2026-11-04 00:33:23 +05:30
commit 74ae93a96e
5 changed files with 94691 additions and 0 deletions

View file

@ -0,0 +1,95 @@
embedded database
**from llm**
Yes — there are several **SQLite-like databases** that:
* ✅ Store everything in a **single file**
* ✅ Don’t require a central server
* ✅ Can store **BSON / document-style data** (instead of strict tables)
Here are the best options depending on what you want:
---
## 1️⃣ **LiteDB** (Very close to what you described)
* Embedded
* Single `.db` file
* No server required
* Stores data as **BSON documents**
* Very similar to MongoDB API
* Great for .NET apps
If you're using C#, this is probably the cleanest choice.
---
## 2️⃣ **MongoDB + Embedded Alternatives**
MongoDB itself requires a server, BUT there are embedded variants:
### 🔹 **Realm**
* Embedded
* Local file storage
* Document-style
* Good for mobile apps
### 🔹 **NeDB**
* Pure JS
* Stores data in a file
* Mongo-like API
* Good for Node.js apps
---
## 3️⃣ **UnQLite**
Very interesting option:
* Embedded (like SQLite)
* Single file
* No server
* Key-value + document store
* JSON-like storage
* Written in C
This is probably the closest SQLite-style NoSQL engine.
---
## 4️⃣ SQLite itself (with JSON)
Even regular **SQLite** supports:
* JSON columns
* JSON queries
* Single-file database
* Zero configuration
If you just need document-style storage without strict schema, SQLite + JSON might already be enough.
---
# 🔎 Quick Comparison
| DB | File-based | Serverless | BSON/Document | Best For |
| ------- | ---------- | ---------- | --------------- | ------------ |
| LiteDB | ✅ | ✅ | ✅ BSON | .NET apps |
| UnQLite | ✅ | ✅ | ✅ JSON-like | C / embedded |
| NeDB | ✅ | ✅ | ✅ JSON | Node.js |
| SQLite | ✅ | ✅ | JSON (not BSON) | General use |
---
If you tell me:
* What language you’re using
* Desktop / web / mobile?
* Approx data size?
I can give you a more precise recommendation.

View file

@ -0,0 +1,281 @@
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);
//}
});
```
 

View file

@ -0,0 +1,302 @@
Shell
Type `mongosh` in terminal to start the shell
- `show databases/dbs` : to show databases
- `show collections` : to show collections
- `use test2` : switch to test2 database. if test2 doesnt exist it will still switch to it. Once the collection is created in non existent database then that database will be created.
- cls : to clear screen
- creating variable
`var name="yoshi"`
then type name in shell it will return `yoshi`
`name = "mario"`
then typing name in shell will return `mario`
- exit : to exit shell
 
**Creating document**
- First add collection using
`db.createCollection('col1')` this
- Inserting document
`db.col1.insertOne({title : "The Color of Magic", author : "Terry Pratchett"})`
We dont have `col2` but if we try to insert document in this collection then this connection will be created
`db.col2.insertOne({title : "title1"})`
for inserting multiple
`db.col1.insertMany([{title: "The light fantastic"}, {title: "title2"}])`
 
**Finding Documents**
- Getting all documents
`db.col1.find()` this is similar to `select * from col2` in sql.
- Using filters in find method
- `db.col1.find({author : "Terry Pratchett",
title :
"The Color of Magic"})`
This will print those document with given fields values
its equal to `select * from col1 where author = 'Terry Pratchett' and title = 'The Color of Magic'`
- `db.col1.find({author : "Terry Pratchett"}, {title: 1, author : 1})`
To specify what field we want instead of getting whole document we can specify that in 2nd parameter of find method.
this is similar to
`select title,author from col1 where author = 'Terry Pratchett'`
To get some field but with no filter
`db.col1.find({}, {title: 1, author : 1})`
just pass empty object as 1st parameter for that
- `db.col1.findOne({_id: ObjectId('66590a00d3c92df2cd286ea0')}`
to find one document and to pass fields which are keys basically as it will just find first document which matched property.
 
**Sorting and Limiting Data**
- `db.col1.find({author : "Terry Pratchett"}).count()`
We can chain methods like this. after getting results, count method will return the count of them
- `db.col1.find().limit(2)`
this will return the first 2 results
- to get 11th to 20th results and not first 20 results use
`db.col1.find().skip(10).limit(10)`
When you chain skip() and limit(), the method chaining order does not affect the results. The server always applies the skip operation based on the sort order before it applies the limit on how many documents to return.
The following code example shows different chaining orders for skip() and limit() that always produce the same query results for the same data set:
```js
db.myColl.find().sort({_id: 1}).skip(3).limit(6);
db.myColl.find().sort({_id: 1}).limit(6).skip(3);
```
- `db.col1.find().sort({title: 1}).limit(2)`
this will sort the documents by title in ascending and return the first 2 results
in order to sort by descending order use
`db.col1.find().sort({title: -1}).limit(2)`
 
**Nested Documents**
- Instead of creating separate collection we can add them as nested documents too to reduce the complexity too
Query
```js
db.books.insertOne({
title: "The Way of Kings",
author: "Brandon Sanderson",
rating: 9,
pages: 320,
genres: ["fantasy"],
reviews: [{
name: "Yoshi",
body: "Great book!!!"
},
{
name: "mario",
body: "So so"
}
]
})
db.books.insertMany(
[{title: "The Light Fantastic",
author: "Terry Pratchett",
pages: 250,
rating: 6,
genres: ["fantasy", "magic"],
reviews: [{name:"luigi", body: "it was pretty good"}, {name: "bowser", body: "loved it!!"}]}, {title: "The Name of the Wind", "author": "Patrick Rothfuss", page: 500, "rating": 10, genres: ["fantasy"], review: [{name: "peach", body: "one of my favs"}]},
{title: "The Color of Magic",
"author": "Terry Pratchett",
page: 350,
"rating": 8,
genres: ["fantasy", "magic"],
review: [{name: "luigi", body: "it was ok"}, {name: "bowser", body: "really good book"}]},
{title: "1984",
"author": "George Orwell",
page: 300,
"rating": 6,
genres: ["sci-fi", "dystopian"], review: [{name: "peach", body: "not my cup of tea"}, {name: "mario", body: "meh"}]}
])
```
**Operations and Complex Queries**
- All operators begin with `$` sign
- gt : greater than
`db.books.find({rating : {$gt : 8}})`
All books with rating greater than 8
- gte : greater than or equal to
- lt : lesser than
- lte : lesser than or equal to
- or
`db.books.find({$or : [ {rating : 7}, {rating: 9} ]})`
this will return those books whose rating is either 7 or 9.
`db.books.find({ $or : [{rating : 7}, {author: "Terry Pratchett" } ] })`
- last example
`db.books.find( {$or : [{pages: {$lt : 300}}, {pages: {$gt: 400} } ]} )`
this will return books with pages less than 300 and pages greater than 400.
- for accessing nested objects
```js
db.col1.insertOne(
{
"obj": {
"data": "lorem"
}
}
)
```
`db.col1.find( { "obj.data": "lorem" } )`
- Summary
```
- Name
= Description
$eq
Matches values that are equal to a specified value.
$gt
Matches values that are greater than a specified value.
$gte
Matches values that are greater than or equal to a specified value.
$in
Matches any of the values specified in an array.
$lt
Matches values that are less than a specified value.
$lte
Matches values that are less than or equal to a specified value.
$ne
Matches all values that are not equal to a specified value.
$nin
Matches none of the values specified in an array.
Logical
- Name
= Description
$and
Joins query clauses with a logical AND returns all documents that match the conditions of both clauses.
$not
Inverts the effect of a query expression and returns documents that do not match the query expression.
$nor
Joins query clauses with a logical NOR returns all documents that fail to match both clauses.
$or
Joins query clauses with a logical OR returns all documents that match the conditions of either clause.
```
 
**in and nin operator**
- in :
`db.books.find({rating : {$in : [7,8,9] }})` : return results whose ratings are either of the values in array. Same can be done with `or`
`db.books.find({$or : [ {rating: 7},{rating: 8},{rating: 9} ] })`
- nin :
`db.books.find({rating : {$nin : [7,8,9] }})` : return results whose ratings are neither of the values in array. Same can be done with `nor`
`db.books.find({$nor : [ {rating: 7},{rating: 8},{rating: 9} ] })`
 
**Querying Arrays**
- Match found
`db.books.find({genres: "fantasy"})`
this will return the documents whose field genre contains fantasy in its array. genre may be only fantasy or it can have more genres too but `fantasy` must be included.
- Only match
As genre is array so to get the only match
`db.books.find({genres: ["fantasy"]})`
this will return documents with field containing this value which is `fantasy` only. we can have magic too so it will return those which contains values `fantasy` and `magic` too.
eg 2: `db.books.find({genres: ["fantasy","magic"]})`
- Match found for given set(all operator)
Only match will only return those with specified but if we want to include those with given set(they can have more but given set must be included) then
`db.books.find({genres: {$all: ["fantasy", "sci-fi"]} })`
- Match found of either of given values
for example if we need those which contains atleast magic or atleast sci-fi in one of them
`db.books.find({ $or: [ {genres: "magic"}, {genres : "sci-fi"} ] })`
- Matching nested documents
review field contains documents itself. Suppose we wanna query those documents whose review have documnets with field name and we want specific name too like 'luigi'(documnets where reviews is posted by user 'luigi') then
`db.books.find({"review.name": "luigi"})`
 
**Deleting Documents**
- `db.books.deleteOne({_id : ObjectId('66592602d3c92df2cd286ea5')})`
this will delete one document with the given `_id` value. we can have different field too but since id is unique so it is recommended.
- `db.books.deleteMany({author : "Terry Pratchett"})`
Unlike deleteOne which will delete only one document and stop its search, this will delete all the documents containing the given value of field
 
**Updating Documents**
- `db.books.updateOne( {_id : ObjectId('66592602d3c92df2cd286ea5') }, {$set : {rating : 8, pages : 350}} )`
set operator is used to change the values of fields of document whose id is ` ObjectId('66592602d3c92df2cd286ea5')`.
- `db.books.updateMany( {author : "Terry Pratchett" }, {$set : {author : "Terry Pratchet"}} )`
to update records of given field. unlike updateOne it will check for every records and wont stop after first match is found.
- inc operator
`db.books.updateOne( {_id: ObjectId('66592602d3c92df2cd286ea2')}, {$inc : {pages : 2} } )`
unlike set it doesnt replace but increment it so in case we dont know the value and wanna increment it then we can use this
To decrement it we can pass just negative number like `-2`
- push and pull
to add or delete contents in array
`db.books.updateOne( {_id: ObjectId('66592602d3c92df2cd286ea2')}, {$pull : {genres : "fantasy"} } )`
to delete `fantasy` from array of genres
`db.books.updateOne( {_id: ObjectId('66592602d3c92df2cd286ea2')}, {$push : {genres : "fantasy"} } )`
to add `fantasy` in array of genres
- each
with push and pull we can only do it for one element of array. for multiple elements we have to each operator
`db.books.updateOne( {_id: ObjectId('66592602d3c92df2cd286ea2')}, {$push : {genres : {$each : ["1","2"] } } } )`
this will push '1' and '2' in array of genres field.
- pullAll
to do same with pull we cant use each but need to use pullAll
`db.books.updateOne( {_id: ObjectId('66592602d3c92df2cd286ea2')}, {$pullAll : {genres : ["1","2"] } } )`
- to update nested document
To update the name from "Yoshi" to "Yosh" in the MongoDB document, you can use the updateOne() method with a filter to match the document and an update operation to modify the nested field within the "reviews" array. Here's an example of how you can do it using MongoDB's shell:
```js
db.books.updateOne(
{ "reviews.name": "Yoshi" }, // Filter to match the document containing the review with name "Yoshi"
{ $set: { "reviews.$.name": "Yosh" } } // Update operation to set the name to "Yosh"
)
```
So `reviews.$.name` refers to the "name" field within the matched element of the "reviews" array. It ensures that only the specific review that matched the query condition (in this case, the review with the name "Yoshi") will have its "name" field updated to "Yosh".
so $ is positional operator
Similary to change array element use
```js
db.books.updateOne(
{ "genres": "fantasy" }, // Filter to match the document containing "fantasy" in the genres array
{ $set: { "genres.$": "fantas" } } // Update operation to set the value to "fantas"
)
```
### Indexes
- By default when we find a document through a filter which is not id it scans all documents. Id field is already indexed. But we can also set another field's values as index too by creating a separate index
![f032aa6d3df03bc2c93731c03346a19e.png](../../../../_resources/f032aa6d3df03bc2c93731c03346a19e.png)
- Its simlar to caching/indexing in order to get results faster
- One thing to be noted that creating index is not appropriate always when the field is write heavy instead of read heavy bcz whenever value is modified or new document is added indexed needs to be updated so it can be costly too if field is write heavy.
- Checking evaluation stats
`db.books.find({ rating : 8 }).explain('executionStats')`
this will return totalDocsExamined as number of all documents
- Creating index
`db.books.createIndex({rating : 8})`
- Print the list of indexed
`db.books.getIndexes()`
Now when checking evaluation stat it will return totalDocsExamined as number of documents where rating of 8 exist
- Deleting index
`db.books.dropIndex({rating : 8})`
 
### Improrting and exporting documents
- To export collection named `books` from database named `new2`
`mongoexport --db new2 --collection books --out ~/Desktop/upload/books.json`
- To import collection named `books` from to database `new3`
`mongoimport --db new3 --collection books --file ~/Desktop/upload/books.json`
- to export whole database named `new2`
`mongodump -d new2 -o ~/Desktop/upload/new2`
- to import database from the dump folder
`mongorestore -d new4 ~/Desktop/upload/new2/new2/`
- Exporting with certain query
`mongosh new2 --quiet --eval 'DBQuery.shellBatchSize = 2000; db.books.find({}).limit(2000).toArray()' > books.json`
as DbQuery.shellBatcjSize is depreciated so use this
`mongosh new2 --quiet --eval 'config.set("displayBatchSize", 2000); db.books.find({}).limit(2000).toArray()' > books.json`
or with a script file containing query
file containing following statement
`printjson(db.books.find({}).limit(2000).toArray() )`
so use this command
`mongosh new2 --eval 'load("./Desktop/upload/query.js")'`
**for remote databases use**
- `mongoexport --uri "mongodb+srv://<username>:<password>@testcluster.7kxguvp.mongodb.net/" --db sample_mflix --collection comments -o ~/Desktop/upload/comments.json`

View file

@ -0,0 +1,33 @@
Theory
https://www.youtube.com/playlist?list=PL4cUxeGkcC9h77dJ-QJlwGlZlTd4ecZOA
- relational database
1 author can have many books whose information are stored in the other table named Books.
![9a6a085c63fcaeb121f425de0d03d4b0.png](../../../../_resources/9a6a085c63fcaeb121f425de0d03d4b0.png)
So we have rows,columns, table and joining
Columns is property
and we use sql queries to use them
- non relational database
Here instead of rows, columns and tables we use collections and documents
Each collection store a specific type of data record like users, authors and books.These records inside collections are called documents
So users is collection unlike table in sql. and instead of containing columns and rows it contains document which is more like js object
![2edcc32c60246452cda407c2da2e3c18.png](../../../../_resources/2edcc32c60246452cda407c2da2e3c18.png)
Here author field has nested object. in sql we would have to use other table for that.
**Installation**
- In arch use
`yay -S mongodb-bin` this will install mongodb server and mongodb shell. Make sure to start mongodb service too by
`systemctl start mongodb`
also install mongodb-tools. `mongodb-org-tools` in case of debian and `mongodb-tools-bin` from aur in case of arch. it is for import, export and other diagonistic tools
&nbsp;
- in linux mint/ubuntu
https://www.mongodb.com/docs/v7.0/tutorial/install-mongodb-on-ubuntu/#std-label-install-mdb-community-ubuntu
**Collections and Documents**
![1a819c18ab7dea9f21918c9abcfae274.png](../../../../_resources/1a819c18ab7dea9f21918c9abcfae274.png)
Mongodb stores data in BSON which is Binary JSON and returns result in JSON.
Each document has a property `_id` which is assigned automatically by mongodb and its data type is 'ObjectId'.

View file

@ -0,0 +1,57 @@
mongoose
https://mongoosejs.com/docs/api/model.html
- findall
`const tasks = await Task.find()`
- sorting
`const tasks = await Task.find().sort({complexity: 1})`
- patching
`const updatedTask = await Task.findByIdAndUpdate(taskID,{complexity},{new: true})`
- inserting using save method
```js
const newTask = new Task({title,complexity})
const savedTask = await newTask.save()
```
- deleting
`const deletedTask = await Task.findByIdAndDelete(taskID)`
&nbsp;
basic program
```js
const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
require('dotenv').config()
const app = express()
app.use(cors())
app.use(express.json())
const PORT = process.env.PORT || 5000
const MONGO_URI= process.env.MONGO_URI || 'mongodb://127.0.0.1:27017/merndb'
mongoose.connect(MONGO_URI).then(()=> console.log('mongodb connnected')).catch(err=>console.log('mongodb connection error'))
const TaskSchema = new mongoose.Schema({title: {type: String, require: true}})
const Task = mongoose.model('Task',TaskSchema)
app.get('/api/tasks', async (req,res)=>{
const tasks = await Task.find();
res.json(tasks);
})
app.post('/api/tasks', async (req,res)=>{
const newTask = new Task({title : req.body.title})
const savedTask = await newTask.save()
res.status(201).json(savedTask)
} )
app.listen(PORT,()=> console.log(`Server running on port ${PORT}`) )
```