
MongoDB Kurulumu ve Temel Operasyonlar: NoSQL Veritabanı Rehberi
MongoDB kurulumu ve temel CRUD operasyonları. Collection oluşturma, belge ekleme, sorgulama, index oluşturma ve aggregation pipeline rehberi.
MongoDB Kurulumu ve Temel Operasyonlar
MongoDB, en popüler NoSQL (belge tabanlı) veritabanıdır. JSON benzeri belgelerle çalışır, esnek şema yapısı sunar ve yatay ölçekleme için idealdir.
MongoDB Ne Zaman Tercih Edilir?
| SQL (MySQL/PostgreSQL) | NoSQL (MongoDB) |
|---|---|
| Yapılandırılmış veri | Yarı yapılandırılmış/esnek veri |
| Karmaşık JOIN'ler | Gömülü belge yapısı |
| ACID işlemleri | Yüksek yazma hızı |
| Finans, ERP | Blog, katalog, IoT, log |
BSON ve Belge Tabanlı Mimari
MongoDB, JSON benzeri belgeleri BSON (Binary JSON) formatında saklar. BSON, JSON'ın binary versiyonudur ve birkaç önemli avantaj sunar:
- Daha zengin veri tipleri: Date, ObjectId, Decimal128, Binary, Regular Expression gibi JSON'da bulunmayan tipler desteklenir
- Daha hızlı parsing: Binary format, string parsing'e göre 3-5 kat daha hızlı işlenir
- Boyut verimliliği: Belge başlıkları ve numerik değerler optimize edilir
Her belgenin maksimum boyutu 16 MB ile sınırlıdır. 16 MB'tan büyük dosyalar (video, büyük log dosyaları) için GridFS API kullanılır; GridFS belgeyi 255 KB chunk'lara böler ve iki ayrı koleksiyonda (fs.files + fs.chunks) saklar.
// ObjectId — 12 byte unique ID (timestamp + machine + pid + counter)
db.urunler.findOne({ _id: ObjectId("507f1f77bcf86cd799439011") })
// Decimal128 — finansal hesaplar için (float yerine)
db.urunler.insertOne({ isim: "Laptop", fiyat: NumberDecimal("15999.99") })
// Date — UTC timestamp
db.siparisler.insertOne({ tarih: new Date(), tutar: 250 })
Kurulum
Ubuntu/Debian:
# MongoDB resmi deposunu ekle
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-7.0.list
apt update
apt install mongodb-org
systemctl enable --now mongod
mongosh # Bağlan
RHEL/Rocky Linux:
# /etc/yum.repos.d/mongodb-org-7.0.repo oluşturun
cat > /etc/yum.repos.d/mongodb-org-7.0.repo << 'EOF'
[mongodb-org-7.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-7.0.asc
EOF
dnf install -y mongodb-org
systemctl enable --now mongod
Docker ile:
docker run -d --name mongodb -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=sifre mongo:7.0
mongosh (MongoDB Shell)
# Bağlan
mongosh
# Kimlik doğrulama ile
mongosh --username admin --password sifre --authenticationDatabase admin
# Uzak sunucu
mongosh "mongodb://admin:[email protected]:27017"
// Yardım
help
db.help()
// Veritabanları
show dbs
use sitem_db
// Koleksiyonlar
show collections
// Çıkış
exit
Veritabanı ve Koleksiyon Oluşturma
// MongoDB otomatik oluşturur (ilk veri ekleyince)
use sitem_db
// Koleksiyon oluştur
db.createCollection("urunler")
// Veya otomatik (ilk insert'te)
db.kullanicilar.insertOne({...})
CRUD Operasyonları
Create (Oluşturma):
// Tek belge ekle
db.kullanicilar.insertOne({
isim: "Ahmet Yılmaz",
email: "[email protected]",
yas: 30,
adres: {
sehir: "Bursa",
ulke: "Türkiye"
},
etiketler: ["musteri", "premium"],
kayit_tarihi: new Date()
});
// Birden fazla belge ekle
db.urunler.insertMany([
{ isim: "Laptop", fiyat: 15000, kategori: "elektronik", stok: 50 },
{ isim: "Mouse", fiyat: 250, kategori: "elektronik", stok: 200 },
{ isim: "Masa", fiyat: 3500, kategori: "mobilya", stok: 15 }
]);
Read (Okuma):
// Tüm belgeler
db.kullanicilar.find()
db.kullanicilar.find().pretty()
// Filtre ile
db.urunler.find({ kategori: "elektronik" })
db.urunler.find({ fiyat: { $gt: 500 } }) // 500'den büyük
db.urunler.find({ fiyat: { $gte: 250, $lte: 5000 } }) // Aralık
// Projeksiyon (belirli alanlar)
db.kullanicilar.find({}, { isim: 1, email: 1, _id: 0 })
// Tek belge
db.urunler.findOne({ isim: "Laptop" })
// Sıralama
db.urunler.find().sort({ fiyat: -1 }) // Azalan
// Limit ve skip
db.urunler.find().limit(10).skip(20) // Sayfalama
// Sayma
db.urunler.countDocuments({ kategori: "elektronik" })
Update (Güncelleme):
// Tek güncelle
db.urunler.updateOne(
{ isim: "Laptop" },
{ $set: { fiyat: 16000, guncelleme: new Date() } }
);
// Birden fazla güncelle
db.urunler.updateMany(
{ kategori: "elektronik" },
{ $inc: { stok: -1 } } // Stoktan 1 azalt
);
// Upsert (yoksa ekle, varsa güncelle)
db.kullanicilar.updateOne(
{ email: "[email protected]" },
{ $set: { isim: "Yeni Kullanıcı" } },
{ upsert: true }
);
// Diziye eleman ekle
db.kullanicilar.updateOne(
{ email: "[email protected]" },
{ $push: { etiketler: "vip" } }
);
Delete (Silme):
// Tek sil
db.urunler.deleteOne({ isim: "Mouse" })
// Çok sil
db.urunler.deleteMany({ stok: 0 })
// Tüm koleksiyonu temizle
db.urunler.deleteMany({})
// Koleksiyonu sil
db.urunler.drop()
Index Yönetimi
// Index oluştur
db.kullanicilar.createIndex({ email: 1 }, { unique: true })
db.urunler.createIndex({ kategori: 1, fiyat: -1 })
// Text index (tam metin arama)
db.urunler.createIndex({ isim: "text", aciklama: "text" })
db.urunler.find({ $text: { $search: "laptop bilgisayar" } })
// Tüm indexler
db.kullanicilar.getIndexes()
// Index sil
db.kullanicilar.dropIndex("email_1")
// Sorgu planı (index kullanımı)
db.urunler.find({ kategori: "elektronik" }).explain("executionStats")
Aggregation Pipeline
// Kategoriye göre gruplay ve ortalama fiyat hesapla
db.urunler.aggregate([
{ $match: { stok: { $gt: 0 } } }, // Filtre
{ $group: {
_id: "$kategori",
ortalama_fiyat: { $avg: "$fiyat" },
toplam: { $sum: 1 }
}},
{ $sort: { ortalama_fiyat: -1 } } // Sırala
]);
// Join benzeri (lookup)
db.siparisler.aggregate([
{ $lookup: {
from: "kullanicilar",
localField: "kullanici_id",
foreignField: "_id",
as: "kullanici_bilgi"
}}
]);
Şema Tasarım Desenleri
MongoDB'de şema tasarımı, ilişkisel veritabanlarından farklı düşünmeyi gerektirir. Üç temel desen vardır:
1. Embedding (Gömülü Belge)
İlgili veriyi tek belgede tutar. Birlikte erişilen veriler için en iyi performansı sunar (tek okuma).
// Sipariş + ürün satırları gömülü
db.siparisler.insertOne({
musteri_id: ObjectId("..."),
tarih: new Date(),
urunler: [
{ sku: "LP-100", isim: "Laptop", adet: 1, fiyat: 15999 },
{ sku: "MS-200", isim: "Mouse", adet: 2, fiyat: 250 }
],
toplam: 16499
})
Ne zaman kullanılır: 1-to-few ilişkiler, sık değişmeyen veri, atomik güncellemeler gerekiyorsa.
2. Referencing (Referans)
İlişkili belgeleri ayrı koleksiyonlarda tutar, ID ile bağlar. SQL JOIN benzeri okumalar için $lookup kullanılır.
db.kullanicilar.insertOne({ _id: 1, isim: "Ali" })
db.siparisler.insertOne({ kullanici_id: 1, tutar: 250 })
// JOIN benzeri sorgu
db.siparisler.aggregate([
{ $lookup: {
from: "kullanicilar",
localField: "kullanici_id",
foreignField: "_id",
as: "musteri"
}}
])
Ne zaman kullanılır: 1-to-many veya many-to-many, bağımsız büyüyen koleksiyonlar, sık güncellenen üst veri.
3. Hybrid (Hibrit)
Sık erişilen alanları gömülü, ayrıntıyı referansta tut. Örneğin blog yazısında son 5 yorum gömülü, tüm yorumlar ayrı koleksiyonda.
Güvenlik Yapılandırması
// Admin kullanıcı oluştur
use admin
db.createUser({
user: "admin",
pwd: "guclu_sifre",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
});
// Uygulama kullanıcısı
use sitem_db
db.createUser({
user: "app_kullanici",
pwd: "app_sifresi",
roles: [{ role: "readWrite", db: "sitem_db" }]
});
# /etc/mongod.conf
security:
authorization: enabled
net:
bindIp: 127.0.0.1 # Sadece lokal
Yedekleme
# Veritabanı yedekle
mongodump --db sitem_db --out /backups/
# Geri yükle
mongorestore --db sitem_db /backups/sitem_db/
# BSON yerine JSON
mongoexport --db sitem_db --collection urunler --out urunler.json
mongoimport --db sitem_db --collection urunler urunler.json
Replica Set ile Yüksek Erişilebilirlik
Bir Replica Set, aynı veriyi tutan 3 (veya daha fazla) MongoDB sunucusundan oluşur. Üretim ortamlarında replica set zorunludur: yedekleme, otomatik failover ve okuma yükü dağıtımı sağlar.
- Primary: Yazma işlemlerini kabul eden tek node
- Secondary: Primary'i takip eden, salt-okunur replikalar
- Election: Primary düşerse Raft tabanlı seçim ile yeni primary 10-30 saniyede belirlenir
# /etc/mongod.conf — primary üzerinde
replication:
replSetName: "rs0"
// Primary'de replica set'i başlat
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1.local:27017" },
{ _id: 1, host: "mongo2.local:27017" },
{ _id: 2, host: "mongo3.local:27017" }
]
})
// Durum kontrol
rs.status()
İstemci tarafında okuma tercihi (readPreference) ile secondary'lere yük dağıtılabilir:
mongosh "mongodb://mongo1,mongo2,mongo3/sitem?replicaSet=rs0&readPreference=secondaryPreferred"
Sharding ile Yatay Ölçekleme
Tek sunucunun RAM/disk kapasitesini aşan veri setleri için sharding kullanılır: veri, shard key üzerinden birden fazla shard'a parçalanır.
- mongos: İstemci ile shard'lar arasındaki query router
- Config Server Replica Set: Shard meta verisini tutar (3 node)
- Shard: Her shard kendi başına bir replica set'tir
Shard key seçimi kritiktir: yüksek kardinalite + dengeli yazma dağılımı + sorgu pattern'lerine uygun olmalı. Yanlış shard key (örn. monotonik artan timestamp) tüm yazmaları tek shard'a yönlendirir ("hot shard").
// Koleksiyonu shard'la
sh.enableSharding("sitem_db")
sh.shardCollection("sitem_db.siparisler", { kullanici_id: "hashed" })
Büyükweb VDS sunucularında MongoDB full root erişimiyle tam kontrol sizde. Node.js, Python veya PHP uygulamalarınız için MongoDB kurulumu yapabilirsiniz.
MongoDB Performans Optimizasyonu
Working Set ve RAM
MongoDB, sıkça erişilen veriyi (working set) RAM'de tutar. RAM, working set'ten küçükse disk I/O artar ve sorgular yavaşlar. Pratik kural: indekslerin tamamı + sıcak veri RAM'e sığmalı.
// Veritabanı boyutu ve indeks boyutu
db.stats()
db.urunler.stats()
db.urunler.totalIndexSize()
Bağlantı Havuzu (Connection Pool)
Sürücüler (Node.js mongodb, Python pymongo, PHP mongodb) varsayılan olarak bağlantı havuzu kullanır. Web uygulamaları için maxPoolSize: 50-100 tipik bir değerdir; her uygulama instance'ı kendi havuzunu yönetir.
// Node.js — connection pool
const { MongoClient } = require('mongodb');
const client = new MongoClient(uri, { maxPoolSize: 50, minPoolSize: 5 });
Yaygın Performans Tuzakları
| Sorun | Çözüm |
|---|---|
| Sınırsız sorgu (limit yok) | Her find()'a .limit(N) ekleyin |
| Sıralı arama (collection scan) | Sorguda kullanılan alana index ekleyin |
Büyük $lookup JOIN'leri |
İlgili veriyi embed edin veya denormalize edin |
| Şişen array'ler (10K+ eleman) | Ayrı koleksiyona ayırın |
| Yüksek belge fragmentasyonu | compact komutu veya yeniden ölçekleme |
MongoDB İzleme (Monitoring)
# Anlık operasyon istatistikleri (insert/query/update/delete per saniye)
mongostat --host mongo.local
# En aktif koleksiyonları gör
mongotop --host mongo.local
# Çalışan sorguları listele (mongosh içinde)
db.currentOp({ active: true, secs_running: { $gt: 1 } })
# Bir sorguyu öldür
db.killOp(<opid>)
// Sunucu durumu — uptime, bağlantı sayısı, opcounters
db.serverStatus()
// Yavaş sorgu profiler (slowMs üstü tüm sorgular kaydedilir)
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)
Üretim ortamında MongoDB Atlas alternatifleri olarak Percona PMM, Datadog veya self-hosted Prometheus + mongodb_exporter tercih edilebilir.
Güvenlik Best Practices
- Authentication zorunlu:
mongod.confiçindesecurity.authorization: enabledmutlaka aktif - bindIp: Varsayılan olarak
127.0.0.1veya VPN/private subnet; asla 0.0.0.0 açıkta bırakmayın - TLS/SSL: İstemci-sunucu trafiği şifrelenmeli (
net.tls.mode: requireTLS) - Role-based Access Control:
readWriteyerine en az yetki prensibi (read, koleksiyon-bazlı roller) - Audit log: Kurumsal sürümde tüm bağlantı/CRUD denetlenebilir
- Default port değişikliği: 27017 yerine farklı port (zayıf koruma ama bot taramalarını engeller)
- Düzenli güncelleme: Major sürüm geçişlerinde release notes ve migration guide takip edin
Sıkça Sorulan Sorular (MongoDB)
MongoDB mi MySQL mi?
Yapılandırılmış ilişkisel veri ve karmaşık JOIN'ler için MySQL/PostgreSQL daha uygundur. Esnek şema, IoT, log toplama, gerçek zamanlı analiz, içerik kataloğu gibi senaryolarda MongoDB öne çıkar. Bazı projelerde iki teknoloji birlikte kullanılır (CRM için PostgreSQL, ürün kataloğu için MongoDB).
Tek sunucu (standalone) yeterli mi?
Geliştirme ortamı için evet, üretimde hayır. Yedekleme ve failover için en az 3 üyeli replica set gereklidir. 3 node maliyet açısından engel değil — Türkiye lokasyonlu VDS paketlerimiz ile 3 ayrı sunucuda kurulum yapılabilir.
MongoDB ile transaction yapılabilir mi?
Evet, MongoDB 4.0+ çoklu-belge ACID transaction'ları destekler (replica set veya sharded cluster gerekli). Ancak transaction'lar performans maliyetlidir; mümkünse şema tasarımıyla atomik tek-belge güncellemelerini tercih edin.
Hangi sürümü kullanmalıyım?
2026 itibarıyla MongoDB 7.0 ve 8.0 üretim için önerilir. 6.0 LTS sürümü hâlâ destekleniyor ancak yeni projeler için 7.0+ tercih edilmelidir. 4.4 ve 5.0 destek dışı.
Hosting önerisi nedir?
MongoDB I/O ve RAM yoğun bir veritabanıdır. NVMe SSD diskli VDS veya dedicated sunucu ideal seçenektir. Çoklu node replica set için 3 ayrı VDS dağıtık konumlandırma sağlar. Detay için E5 v4 VDS paketlerimize veya fiziksel dedicated sunucularımıza göz atabilirsiniz.
İlgili Büyükweb Hizmetleri
Veritabanı performansı ve güvenilirliği için Türkiye lokasyonlu sunucu paketlerimiz:
- Yüksek IOPS VDS Sunucu
- E5 v4 İşlemcili VDS
- Fiziksel Dedicated
- WordPress Hosting (MySQL)
- cPanel Web Hosting
Sorularınız için 0850 302 60 70 numaralı destek hattımıza veya iletişim sayfamıza yazabilirsiniz.
Veritabanı Yönetimi İlgili Hizmetlerimiz
Bu yazıda anlatılan teknik konuyu profesyonel altyapıyla deneyimleyin
Etiketler:

