MongoDB Nedir?
MongoDB, document-oriented NoSQL veritabanıdır. JSON-benzeri BSON formatında verileri depolar ve geleneksel relational veritabanlarına alternative sunar. Scalability, flexibility ve performance odaklıdır.
MongoDB'nin Avantajları
- Schema Flexibility: Dinamik schema yapısı
- Horizontal Scaling: Sharding ile kolay ölçeklendirme
- Rich Query Language: Güçlü sorgulama dili
- High Performance: Memory-mapped files ve indexing
- JSON-like Documents: Uygulama objelerine yakın format
- Aggregation Framework: Güçlü veri analizi
1. MongoDB Kurulumu
MongoDB Community Server
# Ubuntu/Debian
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
# macOS
brew tap mongodb/brew
brew install mongodb-community
# Windows
# MongoDB Compass ile birlikte installer'ı indirin
# https://www.mongodb.com/try/download/community
MongoDB Başlatma
# Service olarak başlat (Linux/macOS)
sudo systemctl start mongod
sudo systemctl enable mongod
# Manuel başlatma
mongod --dbpath /data/db
# Bağlantı test
mongo
# veya
mongosh
MongoDB Compass (GUI)
# MongoDB Compass kurulumu
# GUI tool olarak kullanımı kolay
# Veritabanı görselleştirme ve query tools
# https://www.mongodb.com/products/compass
2. Temel MongoDB Kavramları
Terminology Karşılaştırması
SQL Database → MongoDB
Database → Database
Table → Collection
Row → Document
Column → Field
Index → Index
Table Join → Embedded Documents / Linking
BSON Document Structure
// MongoDB document örneği
{
"_id": ObjectId("507f1f77bcf86cd799439011"),
"name": "John Doe",
"age": 30,
"email": "john@example.com",
"address": {
"street": "123 Main St",
"city": "New York",
"zipCode": "10001"
},
"hobbies": ["reading", "swimming", "coding"],
"isActive": true,
"createdAt": ISODate("2025-08-19T10:30:00Z")
}
3. CRUD Operations
Create (Insert) Operations
# Tek document insert
db.users.insertOne({
name: "Alice Johnson",
age: 28,
email: "alice@example.com",
department: "Engineering"
});
# Birden fazla document insert
db.users.insertMany([
{
name: "Bob Smith",
age: 32,
email: "bob@example.com",
department: "Marketing"
},
{
name: "Carol Davis",
age: 29,
email: "carol@example.com",
department: "Sales"
}
]);
# Insert with custom _id
db.products.insertOne({
_id: "PROD-001",
name: "Laptop",
price: 999.99,
category: "Electronics",
inStock: true
});
Read (Find) Operations
# Tüm documents
db.users.find();
# Pretty format
db.users.find().pretty();
# Tek document bulma
db.users.findOne({ name: "Alice Johnson" });
# Koşullu sorgular
db.users.find({ age: { $gt: 30 } }); # age > 30
db.users.find({ age: { $gte: 25, $lt: 35 } }); # 25 <= age < 35
db.users.find({ department: { $in: ["Engineering", "Sales"] } });
# Logical operators
db.users.find({
$and: [
{ age: { $gte: 25 } },
{ department: "Engineering" }
]
});
db.users.find({
$or: [
{ age: { $lt: 25 } },
{ department: "Marketing" }
]
});
# Field projection (sadece belirli fieldları getir)
db.users.find({}, { name: 1, email: 1, _id: 0 });
# Sorting
db.users.find().sort({ age: 1 }); # Ascending
db.users.find().sort({ age: -1 }); # Descending
# Pagination
db.users.find().skip(10).limit(5);
# Count
db.users.countDocuments({ age: { $gte: 30 } });
Update Operations
# Tek document update
db.users.updateOne(
{ name: "Alice Johnson" },
{ $set: { age: 29, department: "Senior Engineering" } }
);
# Birden fazla document update
db.users.updateMany(
{ department: "Engineering" },
{ $set: { bonus: 1000 } }
);
# Upsert (yoksa insert, varsa update)
db.users.updateOne(
{ email: "david@example.com" },
{
$set: {
name: "David Wilson",
age: 27,
department: "IT"
}
},
{ upsert: true }
);
# Array operations
db.users.updateOne(
{ name: "Alice Johnson" },
{ $push: { skills: "Python" } }
);
db.users.updateOne(
{ name: "Alice Johnson" },
{ $pull: { skills: "Python" } }
);
db.users.updateOne(
{ name: "Alice Johnson" },
{ $addToSet: { skills: { $each: ["JavaScript", "React"] } } }
);
# Increment/Decrement
db.products.updateOne(
{ _id: "PROD-001" },
{ $inc: { views: 1, price: -50 } }
);
Delete Operations
# Tek document silme
db.users.deleteOne({ name: "Bob Smith" });
# Birden fazla document silme
db.users.deleteMany({ department: "Marketing" });
# Collection'daki tüm documents'i silme
db.users.deleteMany({});
# Collection'ı tamamen silme
db.users.drop();
4. Advanced Queries
Array Queries
# Array içinde exact match
db.users.find({ skills: "JavaScript" });
# Array'de birden fazla element
db.users.find({ skills: { $all: ["JavaScript", "React"] } });
# Array size
db.users.find({ skills: { $size: 3 } });
# Array element match with condition
db.users.find({ "skills.0": "Python" }); # First element
# $elemMatch for complex array queries
db.products.find({
reviews: {
$elemMatch: {
rating: { $gte: 4 },
date: { $gte: ISODate("2025-01-01") }
}
}
});
Embedded Document Queries
# Nested field query
db.users.find({ "address.city": "New York" });
# Nested document exact match
db.users.find({
address: {
street: "123 Main St",
city: "New York",
zipCode: "10001"
}
});
# Multiple nested fields
db.users.find({
$and: [
{ "address.city": "New York" },
{ "address.zipCode": { $regex: /^100/ } }
]
});
Regular Expressions
# Case-insensitive search
db.users.find({ name: { $regex: /john/i } });
# Starts with
db.users.find({ email: { $regex: /^alice/ } });
# Contains
db.products.find({ name: { $regex: /laptop/i } });
# Ends with
db.users.find({ email: { $regex: /@gmail\.com$/ } });
5. Aggregation Framework
Basic Aggregation Pipeline
# Group by ve count
db.users.aggregate([
{
$group: {
_id: "$department",
count: { $sum: 1 },
averageAge: { $avg: "$age" }
}
}
]);
# Match, group ve sort
db.sales.aggregate([
{
$match: {
date: { $gte: ISODate("2025-01-01") }
}
},
{
$group: {
_id: "$product",
totalSales: { $sum: "$amount" },
averagePrice: { $avg: "$price" }
}
},
{
$sort: { totalSales: -1 }
},
{
$limit: 10
}
]);
Advanced Aggregation Operators
# $lookup (join operations)
db.orders.aggregate([
{
$lookup: {
from: "products",
localField: "productId",
foreignField: "_id",
as: "productDetails"
}
},
{
$unwind: "$productDetails"
},
{
$project: {
orderDate: 1,
quantity: 1,
"productDetails.name": 1,
"productDetails.price": 1,
totalAmount: {
$multiply: ["$quantity", "$productDetails.price"]
}
}
}
]);
# $project for field transformation
db.users.aggregate([
{
$project: {
name: 1,
email: 1,
age: 1,
ageGroup: {
$switch: {
branches: [
{ case: { $lt: ["$age", 25] }, then: "Young" },
{ case: { $lt: ["$age", 35] }, then: "Adult" },
{ case: { $gte: ["$age", 35] }, then: "Senior" }
],
default: "Unknown"
}
}
}
}
]);
# Date aggregation
db.orders.aggregate([
{
$group: {
_id: {
year: { $year: "$orderDate" },
month: { $month: "$orderDate" }
},
totalOrders: { $sum: 1 },
totalRevenue: { $sum: "$amount" }
}
},
{
$sort: { "_id.year": -1, "_id.month": -1 }
}
]);
6. Indexing
Index Types ve Oluşturma
# Single field index
db.users.createIndex({ email: 1 }); # Ascending
db.users.createIndex({ age: -1 }); # Descending
# Compound index
db.users.createIndex({ department: 1, age: -1 });
# Text index (full-text search)
db.products.createIndex({
name: "text",
description: "text"
});
# Text search kullanımı
db.products.find({ $text: { $search: "laptop gaming" } });
# Geospatial index
db.locations.createIndex({ coordinates: "2dsphere" });
# Geospatial query
db.locations.find({
coordinates: {
$near: {
$geometry: { type: "Point", coordinates: [-73.9857, 40.7484] },
$maxDistance: 1000
}
}
});
# Unique index
db.users.createIndex({ email: 1 }, { unique: true });
# Partial index (conditional)
db.users.createIndex(
{ email: 1 },
{
partialFilterExpression: {
email: { $exists: true }
}
}
);
# TTL index (time-based expiration)
db.sessions.createIndex(
{ createdAt: 1 },
{ expireAfterSeconds: 3600 } # 1 hour
);
Index Management
# List all indexes
db.users.getIndexes();
# Index stats
db.users.getIndexStats();
# Drop index
db.users.dropIndex({ email: 1 });
db.users.dropIndex("email_1");
# Query execution plan
db.users.find({ email: "alice@example.com" }).explain("executionStats");
# Index usage stats
db.runCommand({ collStats: "users", indexDetails: true });
7. Schema Design Patterns
Embedding vs Referencing
# Embedding (One-to-Few relationship)
{
_id: ObjectId("..."),
name: "Blog Post",
content: "...",
comments: [
{
author: "John Doe",
text: "Great post!",
date: ISODate("2025-08-19")
},
{
author: "Jane Smith",
text: "Very helpful!",
date: ISODate("2025-08-20")
}
]
}
# Referencing (One-to-Many relationship)
# Users collection
{
_id: ObjectId("..."),
name: "John Doe",
email: "john@example.com"
}
# Orders collection
{
_id: ObjectId("..."),
userId: ObjectId("..."), # Reference to user
products: [...],
totalAmount: 299.99,
orderDate: ISODate("2025-08-19")
}
Advanced Schema Patterns
# Bucket Pattern (Time-series data)
{
_id: ObjectId("..."),
sensor_id: "sensor_001",
timestamp: ISODate("2025-08-19T10:00:00Z"),
measurements: [
{ time: ISODate("2025-08-19T10:00:00Z"), temperature: 23.5 },
{ time: ISODate("2025-08-19T10:01:00Z"), temperature: 23.7 },
{ time: ISODate("2025-08-19T10:02:00Z"), temperature: 23.6 }
]
}
# Subset Pattern (Large arrays)
# Main document with frequently accessed items
{
_id: ObjectId("..."),
name: "Popular Product",
recent_reviews: [...], # Last 10 reviews
total_reviews: 1000
}
# Separate collection for all reviews
{
_id: ObjectId("..."),
product_id: ObjectId("..."),
review: "...",
rating: 5,
date: ISODate("2025-08-19")
}
8. Transactions
Multi-Document Transactions
# MongoDB 4.0+ replica set gerekli
const session = db.getMongo().startSession();
session.startTransaction();
try {
# Transfer operation
db.accounts.updateOne(
{ _id: "account1" },
{ $inc: { balance: -100 } },
{ session: session }
);
db.accounts.updateOne(
{ _id: "account2" },
{ $inc: { balance: 100 } },
{ session: session }
);
# Transaction log
db.transactions.insertOne({
from: "account1",
to: "account2",
amount: 100,
date: new Date()
}, { session: session });
session.commitTransaction();
} catch (error) {
session.abortTransaction();
throw error;
} finally {
session.endSession();
}
9. Performance Optimization
Query Optimization
# Explain plan analizi
db.users.find({ age: { $gt: 25 }, department: "Engineering" })
.explain("executionStats");
# Index hint
db.users.find({ age: { $gt: 25 } }).hint({ age: 1 });
# Limit kullanımı
db.users.find().limit(10); # İlk 10 document
# Projection ile veri miktarını azalt
db.users.find({}, { name: 1, email: 1, _id: 0 });
# Compound index sıralaması önemli
db.users.createIndex({ department: 1, age: 1 });
# Efficient query for compound index
db.users.find({ department: "Engineering", age: { $gt: 25 } });
Memory ve Storage Optimization
# Database stats
db.stats();
# Collection stats
db.users.stats();
# Index size
db.users.totalIndexSize();
# Compact operation (maintenance)
db.runCommand({ compact: "users" });
# Connection pooling (application level)
const MongoClient = require('mongodb').MongoClient;
const client = new MongoClient(uri, {
maxPoolSize: 10,
maxIdleTimeMS: 30000,
maxConnecting: 2,
connectTimeoutMS: 10000
});
10. Node.js ile MongoDB (Mongoose)
Mongoose Setup
# Installation
npm install mongoose
# Connection
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/myapp', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('Connected to MongoDB');
});
Mongoose Schemas ve Models
// User schema
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
maxlength: 100
},
email: {
type: String,
required: true,
unique: true,
lowercase: true,
validate: {
validator: function(v) {
return /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(v);
},
message: props => `${props.value} is not a valid email!`
}
},
age: {
type: Number,
min: 0,
max: 120
},
department: {
type: String,
enum: ['Engineering', 'Marketing', 'Sales', 'HR']
},
skills: [String],
address: {
street: String,
city: String,
zipCode: String
},
isActive: {
type: Boolean,
default: true
},
createdAt: {
type: Date,
default: Date.now
}
});
// Middleware (pre/post hooks)
userSchema.pre('save', function(next) {
if (this.isModified('name')) {
this.name = this.name.charAt(0).toUpperCase() + this.name.slice(1);
}
next();
});
// Instance methods
userSchema.methods.getFullProfile = function() {
return {
name: this.name,
email: this.email,
department: this.department,
isActive: this.isActive
};
};
// Static methods
userSchema.statics.findByDepartment = function(department) {
return this.find({ department, isActive: true });
};
// Create model
const User = mongoose.model('User', userSchema);
Mongoose CRUD Operations
// Create
const newUser = new User({
name: 'Alice Johnson',
email: 'alice@example.com',
age: 28,
department: 'Engineering',
skills: ['JavaScript', 'React', 'Node.js']
});
newUser.save()
.then(user => console.log('User created:', user))
.catch(err => console.error('Error:', err));
// Create with Model.create()
User.create({
name: 'Bob Smith',
email: 'bob@example.com',
age: 32,
department: 'Marketing'
})
.then(user => console.log('User created:', user));
// Read
User.findById(userId)
.then(user => console.log(user));
User.findOne({ email: 'alice@example.com' })
.select('name email department')
.then(user => console.log(user));
User.find({ age: { $gte: 25 } })
.sort({ createdAt: -1 })
.limit(10)
.then(users => console.log(users));
// Update
User.findByIdAndUpdate(
userId,
{ age: 29, department: 'Senior Engineering' },
{ new: true, runValidators: true }
)
.then(user => console.log('Updated user:', user));
User.updateMany(
{ department: 'Engineering' },
{ $push: { skills: 'TypeScript' } }
)
.then(result => console.log('Modified count:', result.modifiedCount));
// Delete
User.findByIdAndDelete(userId)
.then(user => console.log('Deleted user:', user));
User.deleteMany({ isActive: false })
.then(result => console.log('Deleted count:', result.deletedCount));
11. Security Best Practices
Authentication ve Authorization
# MongoDB user oluşturma
use admin
db.createUser({
user: "adminUser",
pwd: "securePassword123",
roles: ["root"]
});
use myapp
db.createUser({
user: "appUser",
pwd: "appPassword123",
roles: [
{ role: "readWrite", db: "myapp" }
]
});
# Authentication ile bağlantı
mongosh "mongodb://appUser:appPassword123@localhost:27017/myapp"
Network Security
# mongod.conf
security:
authorization: enabled
net:
bindIp: 127.0.0.1,10.0.0.5 # Specific IPs only
port: 27017
# SSL/TLS configuration
net:
ssl:
mode: requireSSL
PEMKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/ca.pem
Data Validation
# Schema validation
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "email"],
properties: {
name: {
bsonType: "string",
description: "must be a string and is required"
},
email: {
bsonType: "string",
pattern: "^.+@.+$",
description: "must be a valid email address"
},
age: {
bsonType: "int",
minimum: 0,
maximum: 120,
description: "must be an integer between 0 and 120"
}
}
}
}
});
Sonuç
MongoDB modern uygulamaların vazgeçilmez NoSQL veritabanıdır. Bu tutorial'da öğrendiklerinizi özetlersek:
MongoDB'nin Güçlü Yönleri:
- Flexible schema yapısı
- Horizontal scaling capabilities
- Rich query language ve aggregation
- High performance indexing
- JSON-like document structure
Best Practices:
- Appropriate indexing strategies
- Efficient schema design patterns
- Query optimization techniques
- Security implementation
- Performance monitoring
MongoDB'yi öğrenmek için pratik projeler yapın ve farklı use case'lerde deneyim kazanın. Document-based thinking'e alışmak relational database background'ından gelenler için önemlidir.