diff --git a/docs/angular/components.md b/docs/angular/components.md
new file mode 100644
index 0000000..52a0037
--- /dev/null
+++ b/docs/angular/components.md
@@ -0,0 +1,80 @@
+# Angular Components
+
+## What is a Component?
+A component controls a patch of screen called a view. It consists of:
+- A TypeScript class (component class)
+- An HTML template
+- Optional CSS styles
+
+## Creating a Component
+```bash
+ng generate component my-component
+# or shorthand
+ng g c my-component
+```
+
+## Component Structure
+```typescript
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-my-component',
+ templateUrl: './my-component.component.html',
+ styleUrls: ['./my-component.component.css']
+})
+export class MyComponent {
+ // Component logic goes here
+ title = 'My Component';
+}
+```
+
+## Component Lifecycle Hooks
+- `ngOnInit()`: Called after the first ngOnChanges
+- `ngOnChanges()`: Called when input properties change
+- `ngDoCheck()`: Custom change detection
+- `ngAfterViewInit()`: Called after the view is initialized
+- `ngOnDestroy()`: Cleanup just before Angular destroys the component
+
+## Component Communication
+
+### Parent to Child: @Input()
+```typescript
+// parent.component.html
+
+
+// child.component.ts
+@Input() message: string;
+```
+
+### Child to Parent: @Output()
+```typescript
+// child.component.ts
+@Output() notify = new EventEmitter();
+
+onClick() {
+ this.notify.emit('Button clicked!');
+}
+
+// parent.component.html
+
+```
+
+## View Encapsulation
+Angular supports three view encapsulation strategies:
+- `ViewEncapsulation.Emulated` (default)
+- `ViewEncapsulation.None`
+- `ViewEncapsulation.ShadowDom`
+
+## Content Projection
+```html
+
+
+ Card Title
+ Card content goes here
+
+
+
+
+
+
+```
diff --git a/docs/angular/forms.md b/docs/angular/forms.md
new file mode 100644
index 0000000..f0e012f
--- /dev/null
+++ b/docs/angular/forms.md
@@ -0,0 +1,217 @@
+# Angular Forms
+
+## Template-Driven Forms
+
+### Basic Setup
+```typescript
+// app.module.ts
+import { FormsModule } from '@angular/forms';
+
+@NgModule({
+ imports: [
+ FormsModule
+ ]
+})
+```
+
+### Basic Form
+```html
+
+```
+
+### Two-way Binding
+```html
+
+```
+
+## Reactive Forms
+
+### Setup
+```typescript
+// app.module.ts
+import { ReactiveFormsModule } from '@angular/forms';
+
+@NgModule({
+ imports: [
+ ReactiveFormsModule
+ ]
+})
+```
+
+### Basic Form
+```typescript
+// In component
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+export class LoginComponent {
+ loginForm: FormGroup;
+
+ constructor(private fb: FormBuilder) {
+ this.loginForm = this.fb.group({
+ email: ['', [Validators.required, Validators.email]],
+ password: ['', [Validators.required, Validators.minLength(6)]]
+ });
+ }
+
+ onSubmit() {
+ if (this.loginForm.valid) {
+ console.log(this.loginForm.value);
+ }
+ }
+}
+```
+
+```html
+
+```
+
+### Form Arrays
+```typescript
+// In component
+export class OrderFormComponent {
+ orderForm: FormGroup;
+
+ constructor(private fb: FormBuilder) {
+ this.orderForm = this.fb.group({
+ items: this.fb.array([this.createItem()])
+ });
+ }
+
+ createItem(): FormGroup {
+ return this.fb.group({
+ name: ['', Validators.required],
+ quantity: [1, [Validators.required, Validators.min(1)]]
+ });
+ }
+
+ get items() {
+ return this.orderForm.get('items') as FormArray;
+ }
+
+ addItem() {
+ this.items.push(this.createItem());
+ }
+
+ removeItem(index: number) {
+ this.items.removeAt(index);
+ }
+}
+```
+
+### Custom Validators
+```typescript
+export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
+ return (control: AbstractControl): {[key: string]: any} | null => {
+ const forbidden = nameRe.test(control.value);
+ return forbidden ? {forbiddenName: {value: control.value}} : null;
+ };
+}
+
+// Usage
+this.heroForm = this.fb.group({
+ name: ['', [
+ Validators.required,
+ forbiddenNameValidator(/bob/i) // <-- Here's how you pass in the custom validator
+ ]]
+});
+```
+
+### Dynamic Forms
+```typescript
+// In component
+export class DynamicFormComponent {
+ form: FormGroup;
+ fields = [
+ { type: 'text', name: 'firstName', label: 'First Name', required: true },
+ { type: 'email', name: 'email', label: 'Email', required: true },
+ { type: 'password', name: 'password', label: 'Password', required: true }
+ ];
+
+ constructor(private fb: FormBuilder) {
+ const group = {};
+ this.fields.forEach(field => {
+ group[field.name] = ['', field.required ? Validators.required : []];
+ });
+ this.form = this.fb.group(group);
+ }
+}
+```
+
+### Form Submission with HTTP
+```typescript
+// In component
+export class UserFormComponent {
+ userForm: FormGroup;
+
+ constructor(private fb: FormBuilder, private http: HttpClient) {
+ this.userForm = this.fb.group({
+ name: ['', Validators.required],
+ email: ['', [Validators.required, Validators.email]]
+ });
+ }
+
+ onSubmit() {
+ if (this.userForm.valid) {
+ this.http.post('/api/users', this.userForm.value).subscribe(
+ response => console.log('Success!', response),
+ error => console.error('Error!', error)
+ );
+ }
+ }
+}
+```
+
+### Cross-Field Validation
+```typescript
+// In component
+this.form = this.fb.group({
+ password: ['', [Validators.required]],
+ confirmPassword: ['', [Validators.required]]
+}, { validator: this.passwordMatchValidator });
+
+passwordMatchValidator(g: FormGroup) {
+ return g.get('password').value === g.get('confirmPassword').value
+ ? null : { 'mismatch': true };
+}
+```
+
+### Form Status Changes
+```typescript
+// In component
+ngOnInit() {
+ this.form.statusChanges.subscribe(status => {
+ console.log('Form status:', status);
+ });
+
+ this.form.get('email').valueChanges.subscribe(value => {
+ console.log('Email changed to:', value);
+ });
+}
+```
diff --git a/docs/angular/routing.md b/docs/angular/routing.md
new file mode 100644
index 0000000..7466240
--- /dev/null
+++ b/docs/angular/routing.md
@@ -0,0 +1,167 @@
+# Angular Routing
+
+## Basic Setup
+
+```typescript
+// app-routing.module.ts
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { HomeComponent } from './home/home.component';
+import { AboutComponent } from './about/about.component';
+
+const routes: Routes = [
+ { path: '', component: HomeComponent },
+ { path: 'about', component: AboutComponent },
+ { path: '**', redirectTo: '' } // Wildcard route for 404
+];
+
+@NgModule({
+ imports: [RouterModule.forRoot(routes)],
+ exports: [RouterModule]
+})
+export class AppRoutingModule { }
+```
+
+## Route Parameters
+
+```typescript
+// Route definition
+{ path: 'product/:id', component: ProductDetailComponent }
+
+// Accessing in component
+import { ActivatedRoute } from '@angular/router';
+
+constructor(private route: ActivatedRoute) {
+ this.route.params.subscribe(params => {
+ this.productId = params['id'];
+ });
+}
+```
+
+## Child Routes
+
+```typescript
+const routes: Routes = [
+ {
+ path: 'products',
+ component: ProductsComponent,
+ children: [
+ { path: '', component: ProductListComponent },
+ { path: ':id', component: ProductDetailComponent },
+ { path: ':id/edit', component: ProductEditComponent }
+ ]
+ }
+];
+```
+
+## Route Guards
+
+### CanActivate
+```typescript
+@Injectable({
+ providedIn: 'root'
+})
+export class AuthGuard implements CanActivate {
+ constructor(private authService: AuthService, private router: Router) {}
+
+ canActivate(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot): boolean {
+ if (this.authService.isLoggedIn()) {
+ return true;
+ }
+ this.router.navigate(['/login']);
+ return false;
+ }
+}
+
+// Usage
+{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }
+```
+
+### Resolve
+```typescript
+@Injectable({ providedIn: 'root' })
+export class ProductResolver implements Resolve {
+ constructor(private productService: ProductService) {}
+
+ resolve(route: ActivatedRouteSnapshot): Observable {
+ return this.productService.getProduct(route.paramMap.get('id'));
+ }
+}
+
+// Usage
+{
+ path: 'product/:id',
+ component: ProductDetailComponent,
+ resolve: {
+ product: ProductResolver
+ }
+}
+```
+
+## Lazy Loading
+
+```typescript
+const routes: Routes = [
+ {
+ path: 'admin',
+ loadChildren: () => import('./admin/admin.module')
+ .then(m => m.AdminModule)
+ }
+];
+```
+
+## Navigation
+
+```typescript
+// In component
+constructor(private router: Router) {}
+
+gotoProduct(id: number) {
+ this.router.navigate(['/product', id]);
+ // or with query params
+ this.router.navigate(['/products'], {
+ queryParams: { page: 1, search: 'angular' }
+ });
+}
+```
+
+## Route Events
+
+```typescript
+constructor(private router: Router) {
+ this.router.events.pipe(
+ filter(event => event instanceof NavigationEnd)
+ ).subscribe((event: NavigationEnd) => {
+ console.log('Navigation ended:', event.url);
+ });
+}
+```
+
+## Route Animations
+
+```typescript
+// In component
+@Component({
+ selector: 'app-root',
+ template: `
+
+
+
+ `,
+ animations: [
+ trigger('routeAnimations', [
+ transition('* <=> *', [
+ style({ opacity: 0 }),
+ animate('300ms', style({ opacity: 1 }))
+ ])
+ ])
+ ]
+})
+export class AppComponent {
+ prepareRoute(outlet: RouterOutlet) {
+ return outlet?.activatedRouteData?.['animation'];
+ }
+}
+```
diff --git a/docs/angular/services.md b/docs/angular/services.md
new file mode 100644
index 0000000..ed74973
--- /dev/null
+++ b/docs/angular/services.md
@@ -0,0 +1,119 @@
+# Angular Services
+
+## What is a Service?
+Services are singleton objects that provide specific functionality throughout the application. They are typically used for:
+- Data fetching and sharing
+- Business logic
+- Logging
+- Authentication
+
+## Creating a Service
+```bash
+ng generate service data
+# or shorthand
+ng g s data
+```
+
+## Basic Service Example
+```typescript
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root' // Makes it a singleton service
+})
+export class DataService {
+ private data: any[] = [];
+
+ constructor() { }
+
+ getData(): any[] {
+ return this.data;
+ }
+
+ addData(item: any): void {
+ this.data.push(item);
+ }
+}
+```
+
+## Dependency Injection
+```typescript
+// In a component
+constructor(private dataService: DataService) {}
+
+// In a module (if not using providedIn: 'root')
+@NgModule({
+ providers: [DataService]
+})
+```
+
+## HTTP Client
+```typescript
+import { HttpClient } from '@angular/common/http';
+import { Observable } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ApiService {
+ private apiUrl = 'https://api.example.com';
+
+ constructor(private http: HttpClient) {}
+
+ getItems(): Observable {
+ return this.http.get(`${this.apiUrl}/items`);
+ }
+
+ addItem(item: any): Observable {
+ return this.http.post(`${this.apiUrl}/items`, item);
+ }
+}
+```
+
+## HTTP Interceptors
+```typescript
+import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
+import { Observable } from 'rxjs';
+
+@Injectable()
+export class AuthInterceptor implements HttpInterceptor {
+ intercept(req: HttpRequest, next: HttpHandler): Observable> {
+ const token = localStorage.getItem('token');
+
+ if (token) {
+ const cloned = req.clone({
+ headers: req.headers.set('Authorization', `Bearer ${token}`)
+ });
+ return next.handle(cloned);
+ }
+
+ return next.handle(req);
+ }
+}
+```
+
+## Error Handling
+```typescript
+import { catchError } from 'rxjs/operators';
+import { throwError } from 'rxjs';
+
+getItems(): Observable {
+ return this.http.get(`${this.apiUrl}/items`).pipe(
+ catchError(error => {
+ console.error('Error fetching items:', error);
+ return throwError('Something went wrong');
+ })
+ );
+}
+```
+
+## Service Lifecycle Hooks
+- `ngOnInit()`: Not available in services
+- `ngOnDestroy()`: Can be used to clean up subscriptions
+
+## Best Practices
+- Keep services focused on a single responsibility
+- Use `providedIn: 'root'` for singleton services
+- Handle errors appropriately
+- Unsubscribe from observables to prevent memory leaks
+- Use interfaces for request/response types
diff --git a/docs/angular/setup.md b/docs/angular/setup.md
new file mode 100644
index 0000000..431c8b7
--- /dev/null
+++ b/docs/angular/setup.md
@@ -0,0 +1,56 @@
+# Angular Setup Guide
+
+## Prerequisites
+- Node.js (v14 or later)
+- npm (v6 or later)
+- Angular CLI (latest stable version)
+
+## Installation
+
+1. Install Angular CLI globally:
+```bash
+npm install -g @angular/cli
+```
+
+2. Verify installation:
+```bash
+ng version
+```
+
+## Creating a New Project
+```bash
+ng new my-angular-app
+cd my-angular-app
+```
+
+## Project Structure
+```
+my-angular-app/
+├── src/
+│ ├── app/ # Your application code
+│ ├── assets/ # Static assets
+│ ├── environments/ # Environment configurations
+│ └── index.html # Main HTML file
+├── angular.json # Angular CLI configuration
+└── package.json # Project dependencies
+```
+
+## Development Server
+```bash
+# Start development server
+ng serve
+
+# Open in browser
+ng serve --open
+```
+
+## Building for Production
+```bash
+ng build --prod
+```
+
+## Common Commands
+- `ng generate component component-name` - Generate a new component
+- `ng generate service service-name` - Generate a new service
+- `ng test` - Run unit tests
+- `ng e2e` - Run end-to-end tests
diff --git a/docs/mongodb/aggregation.md b/docs/mongodb/aggregation.md
new file mode 100644
index 0000000..a380221
--- /dev/null
+++ b/docs/mongodb/aggregation.md
@@ -0,0 +1,375 @@
+# MongoDB Aggregation Framework
+
+## Aggregation Pipeline Stages
+
+### $match
+Filters documents to pass only matching documents to the next stage.
+
+```javascript
+db.orders.aggregate([
+ { $match: { status: "completed", total: { $gt: 100 } } }
+]);
+```
+
+### $group
+Groups documents by specified identifier expressions.
+
+```javascript
+db.orders.aggregate([
+ {
+ $group: {
+ _id: "$customerId",
+ totalSpent: { $sum: "$total" },
+ averageOrder: { $avg: "$total" },
+ orderCount: { $sum: 1 }
+ }
+ }
+]);
+```
+
+### $sort
+Sorts all input documents and returns them in sorted order.
+
+```javascript
+db.products.aggregate([
+ { $sort: { price: -1, name: 1 } }
+]);
+```
+
+### $project
+Reshapes each document by including, excluding, or adding new fields.
+
+```javascript
+db.users.aggregate([
+ {
+ $project: {
+ name: 1,
+ email: 1,
+ yearJoined: { $year: "$joinDate" },
+ _id: 0
+ }
+ }
+]);
+```
+
+### $lookup
+Performs a left outer join to another collection.
+
+```javascript
+db.orders.aggregate([
+ {
+ $lookup: {
+ from: "customers",
+ localField: "customerId",
+ foreignField: "_id",
+ as: "customer"
+ }
+ },
+ { $unwind: "$customer" }
+]);
+```
+
+### $unwind
+Deconstructs an array field to output one document per array element.
+
+```javascript
+db.orders.aggregate([
+ { $unwind: "$items" },
+ { $group: { _id: "$items.productId", total: { $sum: "$items.quantity" } } }
+]);
+```
+
+### $facet
+Processes multiple aggregation pipelines within a single stage.
+
+```javascript
+db.products.aggregate([
+ {
+ $facet: {
+ categories: [
+ { $unwind: "$categories" },
+ { $group: { _id: "$categories", count: { $sum: 1 } } },
+ { $sort: { count: -1 } }
+ ],
+ priceStats: [
+ { $match: { price: { $exists: true } } },
+ {
+ $group: {
+ _id: null,
+ average: { $avg: "$price" },
+ min: { $min: "$price" },
+ max: { $max: "$price" }
+ }
+ }
+ ]
+ }
+ }
+]);
+```
+
+## Aggregation Operators
+
+### Arithmetic Operators
+- `$add`: Adds numbers together
+- `$subtract`: Subtracts two numbers
+- `$multiply`: Multiplies numbers together
+- `$divide`: Divides one number by another
+- `$mod`: Returns the remainder of a division
+
+```javascript
+db.orders.aggregate([
+ {
+ $project: {
+ subtotal: 1,
+ tax: 1,
+ total: {
+ $add: ["$subtotal", "$tax"]
+ },
+ discount: {
+ $multiply: ["$subtotal", 0.1] // 10% discount
+ },
+ finalTotal: {
+ $subtract: [
+ { $add: ["$subtotal", "$tax"] },
+ { $multiply: ["$subtotal", 0.1] }
+ ]
+ }
+ }
+ }
+]);
+```
+
+### String Operators
+- `$concat`: Concatenates strings
+- `$substr`: Returns a substring
+- `$toLower` / `$toUpper`: Converts to lowercase/uppercase
+- `$trim`: Removes whitespace
+
+```javascript
+db.users.aggregate([
+ {
+ $project: {
+ fullName: {
+ $concat: ["$firstName", " ", "$lastName"]
+ },
+ emailLower: { $toLower: "$email" },
+ username: { $substr: ["$email", 0, { $indexOfBytes: ["$email", "@"] }] }
+ }
+ }
+]);
+```
+
+### Date Operators
+- `$year` / `$month` / `$dayOfMonth`: Extracts date parts
+- `$dateToString`: Formats a date as a string
+- `$dateFromString`: Converts a date string to a date object
+
+```javascript
+db.orders.aggregate([
+ {
+ $project: {
+ orderDate: 1,
+ year: { $year: "$orderDate" },
+ month: { $month: "$orderDate" },
+ day: { $dayOfMonth: "$orderDate" },
+ formattedDate: {
+ $dateToString: {
+ format: "%Y-%m-%d",
+ date: "$orderDate"
+ }
+ }
+ }
+ }
+]);
+```
+
+### Conditional Operators
+- `$cond`: Ternary operator
+- `$ifNull`: Returns a value if null, otherwise returns the field value
+- `$switch`: Case/when/default logic
+
+```javascript
+db.products.aggregate([
+ {
+ $project: {
+ name: 1,
+ price: 1,
+ priceCategory: {
+ $switch: {
+ branches: [
+ { case: { $lt: ["$price", 50] }, then: "Budget" },
+ { case: { $lt: ["$price", 200] }, then: "Standard" },
+ { case: { $lt: ["$price", 1000] }, then: "Premium" }
+ ],
+ default: "Luxury"
+ }
+ },
+ discountPrice: {
+ $cond: {
+ if: { $gt: ["$quantity", 10] },
+ then: { $multiply: ["$price", 0.9] }, // 10% discount
+ else: "$price"
+ }
+ },
+ description: { $ifNull: ["$description", "No description available"] }
+ }
+ }
+]);
+```
+
+## Performance Optimization
+
+### Index Usage
+```javascript
+// Create an index for the aggregation
+// db.orders.createIndex({ status: 1, orderDate: -1 });
+
+db.orders.aggregate([
+ { $match: { status: "completed", orderDate: { $gte: new Date("2023-01-01") } } },
+ { $sort: { orderDate: -1 } },
+ { $limit: 100 }
+]);
+```
+
+### $lookup Optimization
+```javascript
+// Instead of this (inefficient with large collections):
+db.orders.aggregate([
+ { $lookup: { from: "products", localField: "productId", foreignField: "_id", as: "product" } },
+ { $unwind: "$product" },
+ { $match: { "product.category": "Electronics" } }
+]);
+
+// Do this (more efficient):
+db.orders.aggregate([
+ {
+ $lookup: {
+ from: "products",
+ let: { productId: "$productId" },
+ pipeline: [
+ { $match: { $expr: { $eq: ["$_id", "$$productId"] }, category: "Electronics" } }
+ ],
+ as: "product"
+ }
+ },
+ { $unwind: "$product" }
+]);
+```
+
+### $redact
+Controls document traversal during processing.
+
+```javascript
+db.employees.aggregate([
+ {
+ $redact: {
+ $cond: {
+ if: { $eq: ["$department", "HR"] },
+ then: "$$DESCEND",
+ else: "$$PRUNE"
+ }
+ }
+ }
+]);
+```
+
+## Aggregation with $graphLookup
+
+### Recursive Lookup
+```javascript
+db.employees.aggregate([
+ {
+ $match: { name: "John Doe" }
+ },
+ {
+ $graphLookup: {
+ from: "employees",
+ startWith: "$reportsTo",
+ connectFromField: "reportsTo",
+ connectToField: "_id",
+ as: "managementChain",
+ maxDepth: 10,
+ depthField: "level"
+ }
+ }
+]);
+```
+
+## Aggregation with $merge
+
+### Output to a Collection
+```javascript
+db.orders.aggregate([
+ { $match: { status: "completed" } },
+ {
+ $group: {
+ _id: { $dateToString: { format: "%Y-%m", date: "$orderDate" } },
+ totalSales: { $sum: "$total" },
+ orderCount: { $sum: 1 }
+ }
+ },
+ { $sort: { _id: 1 } },
+ {
+ $merge: {
+ into: "monthlySales",
+ on: "_id",
+ whenMatched: "replace",
+ whenNotMatched: "insert"
+ }
+ }
+]);
+```
+
+## Aggregation with $setWindowFields (MongoDB 5.0+)
+
+### Moving Averages and Rankings
+```javascript
+db.sales.aggregate([
+ { $match: { date: { $gte: new Date("2023-01-01") } } },
+ { $sort: { productId: 1, date: 1 } },
+ {
+ $setWindowFields: {
+ partitionBy: "$productId",
+ sortBy: { date: 1 },
+ output: {
+ movingAvg: {
+ $avg: "$amount",
+ window: {
+ documents: ["unbounded", "current"]
+ }
+ },
+ salesRank: {
+ $denseRank: {}
+ }
+ }
+ }
+ }
+]);
+```
+
+## Aggregation with $densify
+
+### Filling Gaps in Time Series Data
+```javascript
+db.sensorReadings.aggregate([
+ { $match: { sensorId: "A1", timestamp: { $gte: new Date("2023-01-01") } } },
+ {
+ $densify: {
+ field: "timestamp",
+ range: {
+ step: 1,
+ unit: "hour",
+ bounds: [new Date("2023-01-01"), new Date("2023-01-02")]
+ }
+ }
+ },
+ {
+ $fill: {
+ output: {
+ value: { method: "linear" },
+ status: { value: "interpolated" }
+ }
+ }
+ }
+]);
+```
diff --git a/docs/mongodb/crud.md b/docs/mongodb/crud.md
new file mode 100644
index 0000000..605d144
--- /dev/null
+++ b/docs/mongodb/crud.md
@@ -0,0 +1,262 @@
+# MongoDB CRUD Operations
+
+## Basic CRUD Operations
+
+### 1. Create Operations
+
+#### Insert a Single Document
+```javascript
+// Using insertOne()
+db.collection('users').insertOne({
+ name: 'John Doe',
+ email: 'john@example.com',
+ age: 30,
+ status: 'active'
+});
+```
+
+#### Insert Multiple Documents
+```javascript
+// Using insertMany()
+db.collection('users').insertMany([
+ { name: 'Alice', age: 25, status: 'active' },
+ { name: 'Bob', age: 35, status: 'inactive' },
+ { name: 'Charlie', age: 40, status: 'pending' }
+]);
+```
+
+### 2. Read Operations
+
+#### Find All Documents
+```javascript
+// Using find() with no query
+const allUsers = await db.collection('users').find({}).toArray();
+```
+
+#### Find with Query
+```javascript
+// Find with equality condition
+const activeUsers = await db.collection('users')
+ .find({ status: 'active' })
+ .toArray();
+
+// Using comparison operators
+const adultUsers = await db.collection('users')
+ .find({ age: { $gt: 18 } })
+ .toArray();
+```
+
+#### Find One Document
+```javascript
+const user = await db.collection('users').findOne({ email: 'john@example.com' });
+```
+
+#### Projection (Selecting Fields)
+```javascript
+// Include only name and email fields
+const users = await db.collection('users')
+ .find({}, { projection: { name: 1, email: 1, _id: 0 } })
+ .toArray();
+```
+
+#### Sorting
+```javascript
+// Sort by age in descending order
+const sortedUsers = await db.collection('users')
+ .find()
+ .sort({ age: -1 })
+ .toArray();
+```
+
+#### Limiting and Skipping
+```javascript
+// Pagination: Get second page with 10 items per page
+const page = 2;
+const limit = 10;
+const users = await db.collection('users')
+ .find()
+ .skip((page - 1) * limit)
+ .limit(limit)
+ .toArray();
+```
+
+### 3. Update Operations
+
+#### Update a Single Document
+```javascript
+// Using updateOne()
+const result = await db.collection('users').updateOne(
+ { email: 'john@example.com' },
+ { $set: { status: 'inactive', updatedAt: new Date() } }
+);
+
+console.log(`${result.matchedCount} document(s) matched the filter`);
+console.log(`${result.modifiedCount} document(s) was/were updated`);
+```
+
+#### Update Multiple Documents
+```javascript
+// Using updateMany()
+const result = await db.collection('users').updateMany(
+ { status: 'pending' },
+ { $set: { status: 'active', updatedAt: new Date() } }
+);
+```
+
+#### Increment a Value
+```javascript
+// Increment age by 1
+await db.collection('users').updateOne(
+ { email: 'john@example.com' },
+ { $inc: { age: 1 } }
+);
+```
+
+#### Add to Array
+```javascript
+// Add to array field
+await db.collection('users').updateOne(
+ { email: 'john@example.com' },
+ { $push: { tags: 'premium' } }
+);
+
+// Add to array if not exists
+await db.collection('users').updateOne(
+ { email: 'john@example.com' },
+ { $addToSet: { tags: 'premium' } }
+);
+```
+
+### 4. Delete Operations
+
+#### Delete a Single Document
+```javascript
+const result = await db.collection('users').deleteOne({ email: 'john@example.com' });
+console.log(`${result.deletedCount} document(s) was/were deleted`);
+```
+
+#### Delete Multiple Documents
+```javascript
+const result = await db.collection('users').deleteMany({ status: 'inactive' });
+```
+
+#### Delete All Documents (but keep the collection)
+```javascript
+const result = await db.collection('users').deleteMany({});
+```
+
+## Bulk Operations
+
+### Ordered Bulk Operations
+```javascript
+const bulk = db.collection('users').initializeOrderedBulkOp();
+bulk.insert({ name: 'User 1' });
+bulk.insert({ name: 'User 2' });
+bulk.find({ name: 'User 1' }).update({ $set: { status: 'active' } });
+const result = await bulk.execute();
+```
+
+### Unordered Bulk Operations
+```javascript
+const bulk = db.collection('users').initializeUnorderedBulkOp();
+bulk.insert({ name: 'User 3' });
+bulk.insert({ name: 'User 4' });
+const result = await bulk.execute();
+```
+
+## Find and Modify
+
+### Find One and Update
+```javascript
+const result = await db.collection('users').findOneAndUpdate(
+ { email: 'john@example.com' },
+ { $set: { lastLogin: new Date() } },
+ { returnDocument: 'after' } // Return the updated document
+);
+```
+
+### Find One and Delete
+```javascript
+const result = await db.collection('users').findOneAndDelete(
+ { email: 'john@example.com' }
+);
+```
+
+## Indexes
+
+### Create Index
+```javascript
+// Single field index
+await db.collection('users').createIndex({ email: 1 });
+
+// Compound index
+await db.collection('users').createIndex({ status: 1, createdAt: -1 });
+
+// Unique index
+await db.collection('users').createIndex({ email: 1 }, { unique: true });
+
+// Text index for text search
+await db.collection('articles').createIndex({ content: 'text' });
+```
+
+### List Indexes
+```javascript
+const indexes = await db.collection('users').indexes();
+console.log(indexes);
+```
+
+### Drop Index
+```javascript
+await db.collection('users').dropIndex('email_1');
+```
+
+## Transactions (MongoDB 4.0+)
+
+```javascript
+const session = client.startSession();
+
+try {
+ await session.withTransaction(async () => {
+ // Perform operations in the transaction
+ const user = await db.collection('users').findOne(
+ { email: 'john@example.com' },
+ { session }
+ );
+
+ if (!user) {
+ throw new Error('User not found');
+ }
+
+ await db.collection('orders').insertOne(
+ {
+ userId: user._id,
+ items: ['item1', 'item2'],
+ total: 100,
+ status: 'pending'
+ },
+ { session }
+ );
+
+ await db.collection('users').updateOne(
+ { _id: user._id },
+ { $inc: { orderCount: 1 } },
+ { session }
+ );
+ });
+} finally {
+ await session.endSession();
+}
+```
+
+## Best Practices
+
+1. **Use Projections** to retrieve only the fields you need
+2. **Create Indexes** for frequently queried fields
+3. **Use $lookup** instead of multiple queries when possible
+4. **Batch Operations** for bulk inserts/updates
+5. **Use Cursors** for large result sets
+6. **Monitor Performance** using explain()
+7. **Use Transactions** for multi-document operations that need to be atomic
+8. **Set Write Concerns** appropriately for your use case
+9. **Use TTL Indexes** for expiring data
+10. **Regularly Compact** collections with high churn
diff --git a/docs/mongodb/mongoose.md b/docs/mongodb/mongoose.md
new file mode 100644
index 0000000..aaa0e5f
--- /dev/null
+++ b/docs/mongodb/mongoose.md
@@ -0,0 +1,536 @@
+# Mongoose ODM
+
+## Installation
+```bash
+npm install mongoose
+```
+
+## Basic Setup
+```javascript
+const mongoose = require('mongoose');
+
+// Connect to MongoDB
+mongoose.connect('mongodb://localhost:27017/mydatabase', {
+ useNewUrlParser: true,
+ useUnifiedTopology: true
+});
+
+// Get the default connection
+const db = mongoose.connection;
+
+// Event listeners
+db.on('error', console.error.bind(console, 'MongoDB connection error:'));
+db.once('open', () => {
+ console.log('Connected to MongoDB');
+});
+```
+
+## Defining a Schema
+```javascript
+const { Schema } = mongoose;
+
+const userSchema = new Schema({
+ username: {
+ type: String,
+ required: true,
+ unique: true,
+ trim: true,
+ minlength: 3
+ },
+ email: {
+ type: String,
+ required: true,
+ unique: true,
+ trim: true,
+ lowercase: true,
+ match: [/^\S+@\S+\.\S+$/, 'Please use a valid email address']
+ },
+ password: {
+ type: String,
+ required: true,
+ minlength: 6,
+ select: false // Don't return password by default
+ },
+ role: {
+ type: String,
+ enum: ['user', 'admin'],
+ default: 'user'
+ },
+ createdAt: {
+ type: Date,
+ default: Date.now
+ },
+ updatedAt: {
+ type: Date,
+ default: Date.now
+ },
+ profile: {
+ firstName: String,
+ lastName: String,
+ bio: String,
+ avatar: String
+ },
+ tags: [String],
+ isActive: {
+ type: Boolean,
+ default: true
+ }
+}, {
+ timestamps: true, // Adds createdAt and updatedAt fields
+ toJSON: { virtuals: true }, // Include virtuals when converting to JSON
+ toObject: { virtuals: true } // Include virtuals when converting to objects
+});
+
+// Virtual for full name
+userSchema.virtual('fullName').get(function() {
+ return `${this.profile?.firstName || ''} ${this.profile?.lastName || ''}`.trim();
+});
+
+// Indexes
+userSchema.index({ email: 1 }, { unique: true });
+userSchema.index({ 'profile.firstName': 'text', 'profile.lastName': 'text' });
+
+// Pre-save hook to hash password
+userSchema.pre('save', async function(next) {
+ if (!this.isModified('password')) return next();
+
+ try {
+ const salt = await bcrypt.genSalt(10);
+ this.password = await bcrypt.hash(this.password, salt);
+ next();
+ } catch (error) {
+ next(error);
+ }
+});
+
+// Instance method
+userSchema.methods.comparePassword = async function(candidatePassword) {
+ return await bcrypt.compare(candidatePassword, this.password);
+};
+
+// Static method
+userSchema.statics.findByEmail = function(email) {
+ return this.findOne({ email });
+};
+
+// Query helper
+userSchema.query.byName = function(name) {
+ return this.where({ name: new RegExp(name, 'i') });
+};
+
+const User = mongoose.model('User', userSchema);
+module.exports = User;
+```
+
+## CRUD Operations
+
+### Create
+```javascript
+// Create and save
+const user = new User({
+ username: 'johndoe',
+ email: 'john@example.com',
+ password: 'securepassword123',
+ role: 'user'
+});
+
+await user.save();
+
+// Create in one step
+const newUser = await User.create({
+ username: 'janedoe',
+ email: 'jane@example.com',
+ password: 'securepassword456'
+});
+```
+
+### Read
+```javascript
+// Find all users
+const users = await User.find({});
+
+// Find one user
+const user = await User.findOne({ email: 'john@example.com' });
+
+// Find by ID
+const user = await User.findById('507f1f77bcf86cd799439011');
+
+// Find with conditions
+const activeAdmins = await User.find({
+ role: 'admin',
+ isActive: true
+}).sort({ createdAt: -1 });
+
+// Using query builder
+const users = await User
+ .find({ role: 'user' })
+ .where('createdAt').gt(oneYearAgo)
+ .sort('-createdAt')
+ .limit(10)
+ .select('username email createdAt')
+ .lean();
+```
+
+### Update
+```javascript
+// Update by ID
+const user = await User.findByIdAndUpdate(
+ '507f1f77bcf86cd799439011',
+ { $set: { isActive: false } },
+ { new: true, runValidators: true }
+);
+
+// Update one
+await User.updateOne(
+ { email: 'john@example.com' },
+ { $inc: { loginCount: 1 } }
+);
+
+// Update many
+await User.updateMany(
+ { role: 'user' },
+ { $set: { lastNotified: new Date() } }
+);
+```
+
+### Delete
+```javascript
+// Delete one
+await User.deleteOne({ email: 'john@example.com' });
+
+// Delete by ID
+await User.findByIdAndDelete('507f1f77bcf86cd799439011');
+
+// Delete many
+await User.deleteMany({ isActive: false });
+```
+
+## Middleware (Hooks)
+
+### Document Middleware
+```javascript
+userSchema.pre('save', function(next) {
+ this.updatedAt = new Date();
+ next();
+});
+
+userSchema.post('save', function(doc, next) {
+ console.log(`User ${doc._id} was saved`);
+ next();
+});
+```
+
+### Query Middleware
+```javascript
+userSchema.pre('find', function() {
+ this.start = Date.now();
+});
+
+userSchema.post('find', function(docs) {
+ console.log(`Query took ${Date.now() - this.start} ms`);
+});
+```
+
+### Aggregation Middleware
+```javascript
+userSchema.pre('aggregate', function() {
+ this.pipeline().unshift({ $match: { isActive: true } });
+});
+```
+
+## Population (Joins)
+
+### Basic Population
+```javascript
+const postSchema = new Schema({
+ title: String,
+ content: String,
+ author: { type: Schema.Types.ObjectId, ref: 'User' },
+ comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
+});
+
+const Post = mongoose.model('Post', postSchema);
+
+// Populate author
+const post = await Post.findById(postId).populate('author');
+
+// Populate multiple fields
+const post = await Post.findById(postId)
+ .populate('author')
+ .populate('comments');
+
+// Populate with selected fields
+const post = await Post.findById(postId).populate({
+ path: 'author',
+ select: 'username email profile.firstName profile.lastName'
+});
+
+// Populate with conditions
+const post = await Post.findById(postId).populate({
+ path: 'comments',
+ match: { isApproved: true },
+ options: { sort: { createdAt: -1 }, limit: 10 },
+ select: 'content createdAt',
+ populate: {
+ path: 'author',
+ select: 'username'
+ }
+});
+```
+
+## Aggregation
+
+### Basic Aggregation
+```javascript
+const stats = await User.aggregate([
+ { $match: { isActive: true } },
+ {
+ $group: {
+ _id: '$role',
+ count: { $sum: 1 },
+ averageAge: { $avg: '$age' }
+ }
+ },
+ { $sort: { count: -1 } }
+]);
+```
+
+### Text Search
+```javascript
+const results = await User.find(
+ { $text: { $search: 'john' } },
+ { score: { $meta: 'textScore' } }
+).sort({ score: { $meta: 'textScore' } });
+```
+
+## Transactions
+
+### Basic Transaction
+```javascript
+const session = await mongoose.startSession();
+session.startTransaction();
+
+try {
+ const user = await User.create([{
+ username: 'newuser',
+ email: 'new@example.com',
+ password: 'password123'
+ }], { session });
+
+ await Profile.create([{
+ userId: user[0]._id,
+ firstName: 'New',
+ lastName: 'User'
+ }], { session });
+
+ await session.commitTransaction();
+ console.log('Transaction completed');
+} catch (error) {
+ await session.abortTransaction();
+ console.error('Transaction aborted:', error);
+} finally {
+ session.endSession();
+}
+```
+
+## Plugins
+
+### Creating a Plugin
+```javascript
+// plugins/timestamps.js
+module.exports = function timestampsPlugin(schema) {
+ schema.add({
+ createdAt: { type: Date, default: Date.now },
+ updatedAt: { type: Date, default: Date.now }
+ });
+
+ schema.pre('save', function(next) {
+ this.updatedAt = new Date();
+ next();
+ });
+};
+
+// Using the plugin
+const timestamps = require('./plugins/timestamps');
+userSchema.plugin(timestamps);
+```
+
+## Validation
+
+### Custom Validators
+```javascript
+const userSchema = new Schema({
+ email: {
+ type: String,
+ required: true,
+ validate: {
+ validator: function(v) {
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
+ },
+ message: props => `${props.value} is not a valid email!`
+ }
+ },
+ age: {
+ type: Number,
+ min: [18, 'Must be at least 18, got {VALUE}'],
+ max: 120
+ },
+ role: {
+ type: String,
+ enum: {
+ values: ['user', 'admin'],
+ message: '{VALUE} is not a valid role'
+ }
+ }
+});
+
+// Async validator
+userSchema.path('username').validate({
+ isAsync: true,
+ validator: async function(value) {
+ const user = await this.constructor.findOne({ username: value });
+ return !user || this._id.equals(user._id);
+ },
+ message: 'Username already exists'
+});
+```
+
+## Error Handling
+
+### Handling Validation Errors
+```javascript
+try {
+ const user = await User.create({ email: 'invalid-email' });
+} catch (error) {
+ if (error.name === 'ValidationError') {
+ const errors = {};
+ Object.keys(error.errors).forEach(key => {
+ errors[key] = error.errors[key].message;
+ });
+ return { errors };
+ }
+ throw error;
+}
+```
+
+### Handling Duplicate Key Errors
+```javascript
+try {
+ const user = await User.create({ email: 'duplicate@example.com' });
+} catch (error) {
+ if (error.code === 11000) {
+ return { error: 'Email already exists' };
+ }
+ throw error;
+}
+```
+
+## Performance Optimization
+
+### Lean Queries
+```javascript
+// Returns plain JavaScript objects instead of Mongoose documents
+const users = await User.find({}).lean();
+```
+
+### Select Only Required Fields
+```javascript
+// Only fetch username and email
+const users = await User.find({}, 'username email');
+```
+
+### Use Indexes
+```javascript
+// Create index
+userSchema.index({ email: 1 }, { unique: true });
+userSchema.index({ 'profile.location': '2dsphere' });
+```
+
+### Caching
+```javascript
+// Simple in-memory cache
+const cache = {};
+
+async function getUser(id) {
+ if (cache[id]) {
+ return cache[id];
+ }
+
+ const user = await User.findById(id).cache({ key: id });
+ cache[id] = user;
+ return user;
+}
+```
+
+## Testing
+
+### Using Jest
+```javascript
+// __tests__/user.test.js
+const mongoose = require('mongoose');
+const User = require('../models/User');
+
+beforeAll(async () => {
+ await mongoose.connect('mongodb://localhost:27017/testdb', {
+ useNewUrlParser: true,
+ useUnifiedTopology: true
+ });
+});
+
+afterAll(async () => {
+ await mongoose.connection.dropDatabase();
+ await mongoose.connection.close();
+});
+
+describe('User Model', () => {
+ it('should create a new user', async () => {
+ const user = await User.create({
+ username: 'testuser',
+ email: 'test@example.com',
+ password: 'password123'
+ });
+
+ expect(user).toHaveProperty('_id');
+ expect(user.email).toBe('test@example.com');
+ });
+
+ it('should not create user with duplicate email', async () => {
+ await User.create({
+ username: 'testuser1',
+ email: 'duplicate@example.com',
+ password: 'password123'
+ });
+
+ await expect(
+ User.create({
+ username: 'testuser2',
+ email: 'duplicate@example.com',
+ password: 'password456'
+ })
+ ).rejects.toThrow('duplicate key error');
+ });
+});
+```
+
+## Best Practices
+
+1. **Use Schemas**: Always define schemas for your models
+2. **Use Middleware**: For pre/post hooks and business logic
+3. **Use Virtuals**: For computed properties
+4. **Use Statics**: For model-level functions
+5. **Use Methods**: For document-level functions
+6. **Use Plugins**: For reusable functionality
+7. **Use Lean**: When you don't need Mongoose documents
+8. **Use Projections**: Only fetch the fields you need
+9. **Use Indexes**: For better query performance
+10. **Handle Errors**: Proper error handling and validation
+11. **Use Transactions**: For multi-document operations
+12. **Use Environment Variables**: For configuration
+13. **Use Connection Pooling**: For better performance
+14. **Monitor Performance**: Use MongoDB Atlas or similar tools
+15. **Keep Documents Small**: Avoid large documents (>16MB)
+16. **Use Caching**: For frequently accessed data
+17. **Use Aggregation**: For complex queries
+18. **Use Text Search**: For full-text search capabilities
+19. **Use Geospatial Queries**: For location-based data
+20. **Keep Mongoose Updated**: For security and performance improvements
diff --git a/docs/mongodb/schema-design.md b/docs/mongodb/schema-design.md
new file mode 100644
index 0000000..95ca163
--- /dev/null
+++ b/docs/mongodb/schema-design.md
@@ -0,0 +1,318 @@
+# MongoDB Schema Design
+
+## Data Modeling Concepts
+
+### 1. Document Structure
+
+#### Embedded Documents
+```javascript
+// Users with embedded addresses
+{
+ _id: ObjectId("507f1f77bcf86cd799439011"),
+ name: "John Doe",
+ email: "john@example.com",
+ addresses: [
+ {
+ type: "home",
+ street: "123 Main St",
+ city: "Springfield",
+ zip: "12345",
+ isPrimary: true
+ },
+ {
+ type: "work",
+ street: "456 Work Ave",
+ city: "Springfield",
+ zip: "12345"
+ }
+ ]
+}
+```
+
+#### Referenced Documents
+```javascript
+// Users collection
+{
+ _id: ObjectId("507f1f77bcf86cd799439011"),
+ name: "John Doe",
+ email: "john@example.com"
+}
+
+// Addresses collection
+{
+ _id: ObjectId("5a934e000102030405000000"),
+ userId: ObjectId("507f1f77bcf86cd799439011"),
+ type: "home",
+ street: "123 Main St",
+ city: "Springfield",
+ zip: "12345",
+ isPrimary: true
+}
+```
+
+## Schema Design Patterns
+
+### 1. Embedding (Denormalization)
+**When to use:**
+- One-to-few relationships
+- Data that's always accessed together
+- Data that changes together
+
+**Example: Blog Post with Comments**
+```javascript
+{
+ _id: ObjectId("5a934e000102030405000001"),
+ title: "MongoDB Schema Design",
+ content: "...",
+ author: "John Doe",
+ publishedAt: ISODate("2023-01-15T10:00:00Z"),
+ comments: [
+ {
+ _id: ObjectId("5a934e000102030405000002"),
+ author: "Alice",
+ text: "Great post!",
+ createdAt: ISODate("2023-01-15T11:30:00Z")
+ },
+ {
+ _id: ObjectId("5a934e000102030405000003"),
+ author: "Bob",
+ text: "Thanks for sharing!",
+ createdAt: ISODate("2023-01-16T09:15:00Z")
+ }
+ ]
+}
+```
+
+### 2. Referencing (Normalization)
+**When to use:**
+- One-to-many or many-to-many relationships
+- Large documents that exceed 16MB
+- Frequently updated data
+
+**Example: Products and Categories**
+```javascript
+// Products collection
+{
+ _id: ObjectId("5a934e000102030405000100"),
+ name: "Laptop",
+ price: 999.99,
+ categoryIds: [
+ ObjectId("5a934e000102030405000200"), // Electronics
+ ObjectId("5a934e000102030405000201") // Computers
+ ]
+}
+
+// Categories collection
+{
+ _id: ObjectId("5a934e000102030405000200"),
+ name: "Electronics",
+ description: "Electronic devices"
+}
+
+{
+ _id: ObjectId("5a934e000102030405000201"),
+ name: "Computers",
+ description: "Computers and laptops"
+}
+```
+
+### 3. Bucket Pattern
+**When to use:**
+- Time-series data
+- IoT sensor data
+- Logging
+
+**Example: Sensor Data**
+```javascript
+{
+ _id: "sensor-1-2023-01",
+ sensorId: "sensor-1",
+ type: "temperature",
+ unit: "Celsius",
+ measurements: [
+ { timestamp: ISODate("2023-01-01T00:00:00Z"), value: 21.5 },
+ { timestamp: ISODate("2023-01-01T00:05:00Z"), value: 21.7 },
+ // ... more measurements for the month
+ ],
+ metadata: {
+ location: "Room 101",
+ min: 18.0,
+ max: 25.0
+ }
+}
+```
+
+### 4. Attribute Pattern
+**When to use:**
+- Heterogeneous document attributes
+- Sparse fields
+- Polymorphic schemas
+
+**Example: E-commerce Product Catalog**
+```javascript
+{
+ _id: ObjectId("5a934e000102030405000300"),
+ name: "Smartphone X",
+ category: "electronics",
+ attributes: [
+ { name: "color", value: "black" },
+ { name: "storage", value: "128GB" },
+ { name: "ram", value: "8GB" }
+ ]
+}
+
+{
+ _id: ObjectId("5a934e000102030405000301"),
+ name: "T-Shirt",
+ category: "clothing",
+ attributes: [
+ { name: "color", value: "blue" },
+ { name: "size", value: "L" },
+ { name: "material", value: "cotton" }
+ ]
+}
+```
+
+## Schema Validation
+
+### JSON Schema Validation
+```javascript
+db.createCollection("users", {
+ validator: {
+ $jsonSchema: {
+ bsonType: "object",
+ required: ["name", "email", "status"],
+ properties: {
+ name: {
+ bsonType: "string",
+ description: "must be a string and is required"
+ },
+ email: {
+ bsonType: "string",
+ pattern: "^.+@.+\\.",
+ description: "must be a valid email and is required"
+ },
+ status: {
+ enum: ["active", "inactive", "pending"],
+ description: "must be a valid status and is required"
+ },
+ age: {
+ bsonType: ["int", "null"],
+ minimum: 0,
+ maximum: 120,
+ description: "must be an integer between 0 and 120"
+ }
+ }
+ }
+ }
+});
+```
+
+## Data Types
+
+### Common Data Types
+- String (`string`)
+- Number (`int32`, `int64`, `double`)
+- Boolean (`bool`)
+- Date (`date`)
+- Array (`array`)
+- Object (`object`)
+- ObjectId (`objectId`)
+- Binary Data (`binData`)
+- Null (`null`)
+
+### Special Types
+- Decimal128 (for precise decimal arithmetic)
+- Timestamp (for internal MongoDB use)
+- Regular Expression (`regex`)
+- JavaScript (`javascript`)
+- MinKey/MaxKey (for comparison operations)
+
+## Indexing Strategies
+
+### Single Field Index
+```javascript
+db.users.createIndex({ email: 1 });
+```
+
+### Compound Index
+```javascript
+db.orders.createIndex({ customerId: 1, orderDate: -1 });
+```
+
+### Multikey Index (for arrays)
+```javascript
+db.products.createIndex({ tags: 1 });
+```
+
+### Text Index
+```javascript
+db.articles.createIndex({ title: "text", content: "text" });
+```
+
+### Wildcard Index
+```javascript
+db.users.createIndex({ "metadata.$**": 1 });
+```
+
+## Sharding Strategies
+
+### Hashed Sharding
+```javascript
+sh.shardCollection("mydb.users", { _id: "hashed" });
+```
+
+### Ranged Sharding
+```javascript
+sh.shardCollection("mydb.orders", { customerId: 1 });
+```
+
+### Zoned Sharding
+```javascript
+sh.addShardTag("shard0000", "US");
+sh.addShardTag("shard0001", "EU");
+sh.addTagRange("mydb.users", { country: "US" }, { country: "US" }, "US");
+sh.addTagRange("mydb.users", { country: "UK" }, { country: "FR" }, "EU");
+```
+
+## Data Lifecycle Management
+
+### TTL Indexes
+```javascript
+// Documents will be automatically deleted after 30 days
+db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 });
+```
+
+### Capped Collections
+```javascript
+// Create a capped collection of 1MB
+db.createCollection("recent_activities", { capped: true, size: 1048576 });
+```
+
+## Schema Evolution
+
+### Adding Fields
+```javascript
+db.users.updateMany(
+ { newField: { $exists: false } },
+ { $set: { newField: "default value" } }
+);
+```
+
+### Migrating Data
+```javascript
+// Add new structure
+db.products.updateMany(
+ {},
+ { $set: { "metadata.tags": [] } }
+);
+
+// Migrate old tags to new structure
+db.products.updateMany(
+ { tags: { $exists: true } },
+ [
+ { $set: { "metadata.tags": "$tags" } },
+ { $unset: "tags" }
+ ]
+);
+```
diff --git a/docs/mongodb/setup.md b/docs/mongodb/setup.md
new file mode 100644
index 0000000..f098700
--- /dev/null
+++ b/docs/mongodb/setup.md
@@ -0,0 +1,211 @@
+# MongoDB Setup Guide
+
+## Installation
+
+### macOS (using Homebrew)
+```bash
+# Install MongoDB Community Edition
+brew tap mongodb/brew
+brew install mongodb-community
+
+# Start MongoDB
+brew services start mongodb-community
+
+# Verify installation
+mongod --version
+mongo --version
+```
+
+### Windows
+1. Download MongoDB Community Server from [MongoDB Download Center](https://www.mongodb.com/try/download/community)
+2. Run the installer and follow the prompts
+3. Add MongoDB's `bin` directory to your system's PATH
+4. Create a data directory: `C:\data\db`
+5. Start MongoDB: `mongod`
+
+### Linux (Ubuntu/Debian)
+```bash
+# Import the public key
+wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -
+
+# Create list file
+echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
+
+# Reload local package database
+sudo apt-get update
+
+# Install MongoDB
+sudo apt-get install -y mongodb-org
+
+# Start MongoDB
+sudo systemctl start mongod
+
+# Enable automatic startup
+sudo systemctl enable mongod
+```
+
+## MongoDB Compass (GUI Tool)
+Download and install MongoDB Compass from: https://www.mongodb.com/try/download/compass
+
+## Basic Commands
+
+### Start MongoDB Shell
+```bash
+mongosh # For MongoDB 6.0+
+# or
+mongo # For older versions
+```
+
+### Show Databases
+```javascript
+show dbs
+```
+
+### Switch/Create Database
+```javascript
+use mydb
+```
+
+### Show Collections
+```javascript
+show collections
+```
+
+### Get Help
+```javascript
+db.help()
+```
+
+## Connecting with Node.js
+
+### Install MongoDB Driver
+```bash
+npm install mongodb
+```
+
+### Basic Connection
+```javascript
+const { MongoClient } = require('mongodb');
+
+// Connection URI
+const uri = 'mongodb://localhost:27017';
+
+// Create a new MongoClient
+const client = new MongoClient(uri);
+
+async function run() {
+ try {
+ // Connect the client to the server
+ await client.connect();
+ console.log('Connected successfully to MongoDB');
+
+ // Get the database
+ const db = client.db('mydb');
+
+ // Get the collection
+ const collection = db.collection('documents');
+
+ // Insert a document
+ await collection.insertOne({ name: 'Test', value: 1 });
+
+ // Find documents
+ const docs = await collection.find({}).toArray();
+ console.log('Found documents:', docs);
+
+ } finally {
+ // Close the connection
+ await client.close();
+ }
+}
+
+run().catch(console.dir);
+```
+
+## Configuration
+
+### MongoDB Configuration File (mongod.conf)
+Typical location:
+- Linux: `/etc/mongod.conf`
+- macOS: `/usr/local/etc/mongod.conf`
+- Windows: `C:\Program Files\MongoDB\Server\\bin\mongod.cfg`
+
+### Common Configuration Options
+```yaml
+# Network interfaces
+net:
+ port: 27017
+ bindIp: 127.0.0.1 # Only localhost
+
+# Storage
+dbPath: /data/db
+
+# Security
+security:
+ authorization: enabled # Enable authentication
+
+# Replication (for replica sets)
+replication:
+ replSetName: "rs0"
+
+# Performance
+storage:
+ journal:
+ enabled: true
+ wiredTiger:
+ engineConfig:
+ cacheSizeGB: 1 # Adjust based on available RAM
+```
+
+## Authentication
+
+### Create Admin User
+```javascript
+use admin
+db.createUser({
+ user: 'admin',
+ pwd: 'your-secure-password',
+ roles: [ { role: 'userAdminAnyDatabase', db: 'admin' } ]
+})
+```
+
+### Connect with Authentication
+```javascript
+const uri = 'mongodb://admin:your-secure-password@localhost:27017/admin';
+const client = new MongoClient(uri);
+```
+
+## Backup and Restore
+
+### Create Backup
+```bash
+mongodump --uri="mongodb://localhost:27017" --out=/backup/$(date +%Y%m%d)
+```
+
+### Restore from Backup
+```bash
+mongorestore --uri="mongodb://localhost:27017" /backup/20231015/mydb
+```
+
+## Monitoring
+
+### Basic Stats
+```javascript
+db.serverStatus()
+
+db.stats()
+
+// Collection stats
+db.collection.stats()
+
+// Current operations
+db.currentOp()
+```
+
+### Enable Profiling
+```javascript
+// Set profiling level (0=off, 1=slow, 2=all)
+db.setProfilingLevel(1, { slowms: 100 })
+
+// View profile data
+db.system.profile.find().pretty()
+```
diff --git a/docs/ui/css-tricks.md b/docs/ui/css-tricks.md
new file mode 100644
index 0000000..4be1bf7
--- /dev/null
+++ b/docs/ui/css-tricks.md
@@ -0,0 +1,581 @@
+# CSS Tricks and Tips
+
+## Layout
+
+### Flexbox Centering
+Center elements both horizontally and vertically:
+```css
+.container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh; /* Optional: for full viewport height */
+}
+```
+
+### CSS Grid Layout
+Create a responsive grid with auto-fill:
+```css
+.grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
+ gap: 1rem;
+}
+```
+
+### Sticky Footer
+Keep footer at the bottom of the page:
+```css
+body {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+}
+
+main {
+ flex: 1;
+}
+```
+
+## Effects
+
+### Smooth Scrolling
+```css
+html {
+ scroll-behavior: smooth;
+}
+```
+
+### Custom Scrollbar
+```css
+/* WebKit (Chrome, Safari, newer Edge) */
+::-webkit-scrollbar {
+ width: 10px;
+}
+
+::-webkit-scrollbar-track {
+ background: #f1f1f1;
+}
+
+::-webkit-scrollbar-thumb {
+ background: #888;
+ border-radius: 5px;
+}
+
+/* Firefox */
+html {
+ scrollbar-width: thin;
+ scrollbar-color: #888 #f1f1f1;
+}
+```
+
+### Hover Effects
+```css
+.button {
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+}
+
+.button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+```
+
+## Typography
+
+### Text Overflow Ellipsis
+```css
+.ellipsis {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 100%;
+}
+
+/* Multi-line ellipsis (3 lines) */
+.multi-line-ellipsis {
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+```
+
+### System Font Stack
+```css
+body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ "Helvetica Neue", Arial, sans-serif;
+}
+```
+
+## Responsive Design
+
+### Mobile-First Media Queries
+```css
+/* Base styles (mobile) */
+.container {
+ padding: 1rem;
+}
+
+/* Tablet */
+@media (min-width: 768px) {
+ .container {
+ padding: 2rem;
+ }
+}
+
+/* Desktop */
+@media (min-width: 1024px) {
+ .container {
+ max-width: 1200px;
+ margin: 0 auto;
+ }
+}
+```
+
+### Responsive Images
+```css
+.responsive-img {
+ max-width: 100%;
+ height: auto;
+ display: block;
+}
+
+/* Art direction with picture element */
+
+
+
+
+
+```
+
+## Animations
+
+### Keyframe Animation
+```css
+@keyframes fadeIn {
+ from { opacity: 0; transform: translateY(20px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+.animate-fade-in {
+ animation: fadeIn 0.6s ease-out forwards;
+}
+```
+
+### Hover Underline Animation
+```css
+.hover-underline {
+ position: relative;
+ text-decoration: none;
+}
+
+.hover-underline::after {
+ content: '';
+ position: absolute;
+ width: 0;
+ height: 2px;
+ bottom: -2px;
+ left: 0;
+ background-color: currentColor;
+ transition: width 0.3s ease;
+}
+
+.hover-underline:hover::after {
+ width: 100%;
+}
+```
+
+## Forms
+
+### Custom Checkbox/Radio
+```css
+.custom-checkbox {
+ position: relative;
+ padding-left: 30px;
+ cursor: pointer;
+}
+
+.custom-checkbox input {
+ position: absolute;
+ opacity: 0;
+ cursor: pointer;
+ height: 0;
+ width: 0;
+}
+
+.checkmark {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 20px;
+ width: 20px;
+ background-color: #eee;
+ border: 2px solid #ddd;
+ border-radius: 4px;
+}
+
+.custom-checkbox:hover input ~ .checkmark {
+ background-color: #ccc;
+}
+
+.custom-checkbox input:checked ~ .checkmark {
+ background-color: #2196F3;
+ border-color: #2196F3;
+}
+
+.checkmark:after {
+ content: "";
+ position: absolute;
+ display: none;
+}
+
+.custom-checkbox input:checked ~ .checkmark:after {
+ display: block;
+}
+
+.custom-checkbox .checkmark:after {
+ left: 6px;
+ top: 2px;
+ width: 5px;
+ height: 10px;
+ border: solid white;
+ border-width: 0 2px 2px 0;
+ transform: rotate(45deg);
+}
+```
+
+## Variables and Theming
+
+### CSS Custom Properties
+```css
+:root {
+ --primary-color: #3498db;
+ --secondary-color: #2ecc71;
+ --spacing-unit: 1rem;
+ --border-radius: 4px;
+ --transition: all 0.3s ease;
+}
+
+.button {
+ background-color: var(--primary-color);
+ padding: calc(var(--spacing-unit) * 2);
+ border-radius: var(--border-radius);
+ transition: var(--transition);
+}
+
+/* Dark mode theming */
+@media (prefers-color-scheme: dark) {
+ :root {
+ --primary-color: #2980b9;
+ --secondary-color: #27ae60;
+ }
+}
+```
+
+## Performance
+
+### Will-Change Property
+```css
+.optimize {
+ will-change: transform, opacity;
+}
+```
+
+### Content Visibility
+```css
+.long-content {
+ content-visibility: auto;
+ contain-intrinsic-size: 0 500px; /* Estimated height */
+}
+```
+
+## Browser Compatibility
+
+### Feature Queries
+```css
+@supports (display: grid) {
+ .container {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
+ }
+}
+
+@supports not (display: grid) {
+ .container {
+ display: flex;
+ flex-wrap: wrap;
+ }
+
+ .container > * {
+ flex: 1 1 250px;
+ margin: 0.5rem;
+ }
+}
+```
+
+### Vendor Prefixes
+```css
+.gradient-bg {
+ background: #1e5799; /* Fallback */
+ background: -moz-linear-gradient(top, #1e5799 0%, #2989d8 100%);
+ background: -webkit-linear-gradient(top, #1e5799 0%,#2989d8 100%);
+ background: linear-gradient(to bottom, #1e5799 0%,#2989d8 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(
+ startColorstr='#1e5799',
+ endColorstr='#2989d8',
+ GradientType=0
+ );
+}
+```
+
+## Debugging
+
+### Debugging Layout
+```css
+/* Add to any element to debug */
+.debug {
+ outline: 1px solid red;
+ background: rgba(255, 0, 0, 0.1);
+}
+
+/* Debug all elements */
+* { outline: 1px solid rgba(255, 0, 0, 0.2); }
+* * { outline: 1px solid rgba(0, 255, 0, 0.2); }
+* * * { outline: 1px solid rgba(0, 0, 255, 0.2); }
+* * * * { outline: 1px solid rgba(255, 0, 255, 0.2); }
+* * * * * { outline: 1px solid rgba(0, 255, 255, 0.2); }
+```
+
+### Print Styles
+```css
+@media print {
+ /* Hide elements when printing */
+ .no-print {
+ display: none !important;
+ }
+
+ /* Page breaks */
+ .page-break {
+ page-break-before: always;
+ }
+
+ /* Prevent text from breaking across pages */
+ p, h1, h2, h3, h4, h5, h6 {
+ page-break-inside: avoid;
+ }
+
+ /* Set page margins */
+ @page {
+ margin: 2cm;
+ }
+}
+```
+
+## Modern CSS
+
+### Aspect Ratio
+```css
+.aspect-ratio-box {
+ aspect-ratio: 16 / 9;
+ background: #f0f0f0;
+}
+```
+
+### CSS Grid Subgrid
+```css
+.grid-container {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 1rem;
+}
+
+.grid-item {
+ display: grid;
+ grid-template-rows: subgrid;
+ grid-row: span 3; /* Number of rows this item spans */
+}
+```
+
+### Container Queries
+```css
+.component {
+ container-type: inline-size;
+}
+
+@container (min-width: 400px) {
+ .component .content {
+ display: flex;
+ gap: 1rem;
+ }
+}
+```
+
+## Accessibility
+
+### Screen Reader Only
+```css
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border-width: 0;
+}
+
+/* For interactive elements that need to be visible on focus */
+.sr-only.focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ padding: 0.5em;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+ white-space: normal;
+}
+```
+
+### Reduced Motion
+```css
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+}
+```
+
+## Bonus: CSS Reset
+```css
+/* Box sizing rules */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+/* Remove default margin and padding */
+html,
+body,
+h1, h2, h3, h4, h5, h6,
+p, blockquote, pre,
+dl, dd, ol, ul,
+figure,
+fieldset, legend,
+textarea,
+pre, iframe,
+hr {
+ margin: 0;
+ padding: 0;
+}
+
+/* Set core body defaults */
+body {
+ min-height: 100vh;
+ scroll-behavior: smooth;
+ text-rendering: optimizeSpeed;
+ line-height: 1.5;
+}
+
+/* Remove list styles on ul, ol elements */
+ul[class],
+ol[class] {
+ list-style: none;
+}
+
+/* Make images easier to work with */
+img,
+picture,
+video,
+canvas,
+svg {
+ max-width: 100%;
+ display: block;
+}
+
+/* Inherit fonts for inputs and buttons */
+input,
+button,
+textarea,
+select {
+ font: inherit;
+}
+
+/* Remove all animations and transitions for people that prefer not to see them */
+@media (prefers-reduced-motion: reduce) {
+ * {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+}
+```
+
+## CSS Variables for Theming
+```css
+:root {
+ /* Colors */
+ --color-primary: #2563eb;
+ --color-secondary: #7c3aed;
+ --color-success: #10b981;
+ --color-warning: #f59e0b;
+ --color-danger: #ef4444;
+
+ /* Typography */
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ --font-mono: 'Fira Code', 'Courier New', monospace;
+
+ /* Spacing */
+ --space-xs: 0.25rem;
+ --space-sm: 0.5rem;
+ --space-md: 1rem;
+ --space-lg: 2rem;
+ --space-xl: 4rem;
+
+ /* Border radius */
+ --radius-sm: 0.25rem;
+ --radius-md: 0.5rem;
+ --radius-lg: 1rem;
+ --radius-full: 9999px;
+
+ /* Shadows */
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ --shadow-md: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+ --shadow-lg: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
+
+ /* Transitions */
+ --transition-fast: 150ms ease;
+ --transition-normal: 300ms ease;
+ --transition-slow: 500ms ease;
+}
+
+/* Dark mode */
+@media (prefers-color-scheme: dark) {
+ :root {
+ --color-primary: #3b82f6;
+ --color-secondary: #8b5cf6;
+ --color-success: #10b981;
+ --color-warning: #f59e0b;
+ --color-danger: #ef4444;
+
+ --shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.3);
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
+ --shadow-md: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
+ --shadow-lg: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
+ }
+}
+```
+
+This CSS tricks guide covers a wide range of techniques from basic to advanced, including layout, animations, responsive design, accessibility, and modern CSS features. Each example is ready to use and includes comments for better understanding.