MongoDB'de veritabanı ve koleksiyon oluşturmak için çoğu zaman ayrı bir komut çalıştırmanız gerekmez: mongosh içinde use magaza yazıp ardından db.urunler.insertOne({ ad: "Kalem" }) çalıştırdığınızda hem magaza veritabanı hem de urunler koleksiyonu ilk veri yazıldığı anda kendiliğinden oluşur. Boyut sınırı, doğrulama kuralı ya da varsayılan collation gibi seçeneklere ihtiyacınız varsa db.createCollection() ile koleksiyonu açıkça yaratırsınız. Silmek için koleksiyonda drop(), veritabanında db.dropDatabase() kullanılır.

Bu yazıda use komutunun gerçekte ne yaptığını, koleksiyonların ne zaman ve nasıl oluştuğunu, mevcut koleksiyonları listelemenin yollarını, yeniden adlandırma ve silme işlemlerini, isimlendirme kurallarını ve yeni başlayanların sık düştüğü hataları resmî MongoDB 9.0 ve mongosh belgelerine dayanarak anlatıyoruz. MongoDB'ye yeni başlıyorsanız önce MongoDB nedir ve mongosh kullanımı yazılarına göz atmanız işinizi kolaylaştırır.

Veritabanı, koleksiyon ve belge ilişkisi

Veritabanı, koleksiyon ve belge ilişkisi: Veritabanı, Tablo, Satır, Birincil anahtar

MongoDB veri kayıtlarını belge (document) olarak saklar; belgeler BSON biçimindedir ve koleksiyonlar içinde durur. Bir veritabanı ise bir ya da daha fazla koleksiyonu barındırır. Resmî belgeler koleksiyonları ilişkisel veritabanlarındaki tablolara benzetir. Fark şurada: varsayılan durumda bir koleksiyondaki belgeler ortak bir şemaya bağlı değildir; alan adları ve veri tipleri belgeden belgeye değişebilir. Bir kuralı zorunlu kılmak isterseniz şema doğrulama eklersiniz; bunun ayrıntısı MongoDB şema doğrulama yazısında.

Bir koleksiyonun tam adına namespace denir ve <veritabanı>.<koleksiyon> biçimindedir; örneğin magaza.urunler. Bu ayrıntı önemsiz gibi görünse de isim uzunluğu sınırı tam olarak bu birleşik ad üzerinden hesaplanır. Ayrıca her koleksiyona değişmeyen bir UUID atanır ve bu kimlik replica set üyeleri ile shard'lar arasında aynı kalır. UUID değerini listCollections komutu ya da db.getCollectionInfos() ile görebilirsiniz.

İlişkisel kavramMongoDB karşılığıNot
VeritabanıVeritabanıİlk veri yazıldığında oluşur
TabloKoleksiyonVarsayılan olarak şema dayatmaz
SatırBelgeBSON, en fazla 16 MiB
Birincil anahtar_id alanıKoleksiyonda benzersiz olmalı

Terimlerin daha geniş karşılaştırması için MongoDB ve SQL karşılaştırması yazısına, ilişkisel ve NoSQL modellerinin genel farkı için veritabanı türleri rehberine bakabilirsiniz.

use komutu: veritabanına geçmek ve oluşturmak

mongosh açıldığında hangi veritabanında olduğunuzu görmek için sadece db yazmanız yeterli. Belgelere göre bağlantı sırasında başka bir ad vermediyseniz varsayılan veritabanı test olur. Başka bir veritabanına geçmek için use <ad> yardımcısını kullanırsınız. Sunucudaki veritabanlarını listelemek için show dbs komutu vardır; show databases da aynı işi yapan bir takma addır. Erişim denetimi açıksa bu liste, kullanıcınızın yetkilerine göre değişir.

javascript
db
show dbs
use magaza
db.urunler.insertOne( { ad: "Kalem", fiyat: 15 } )
show collections

Buradaki kritik nokta şu: use magaza tek başına diske hiçbir şey yazmaz. Belgeler, MongoDB'nin veritabanını o veritabanı için ilk kez veri sakladığınızda oluşturduğunu söyler. Yani use çalıştırıp hiçbir şey eklemeden show dbs derseniz yeni adı listede göremezsiniz. Bu durum bir hata değildir; veritabanı henüz fiziksel olarak yoktur. Yukarıdaki örnekte insertOne() çağrısı hem veritabanını hem koleksiyonu yaratır, ardından show collections çıktısında urunler görünür.

Bulunduğunuz veritabanını değiştirmeden başka bir veritabanına erişmek isterseniz db.getSiblingDB() yöntemini kullanabilirsiniz. Bu, özellikle bir script içinde birden fazla veritabanıyla çalışırken use satırlarıyla bağlamı sürekli değiştirmekten daha okunaklıdır.

javascript
const rapor = db.getSiblingDB("raporlar")
rapor.gunluk.insertOne( { tarih: new Date(), adet: 0 } )

Koleksiyon oluşturmanın üç yolu

1. Örtük oluşturma: ilk yazma işlemiyle

Koleksiyon yoksa MongoDB onu, o koleksiyona ilk veri kaydettiğiniz anda oluşturur. Belgeler yalnızca insertOne() değil createIndex() çağrısının da koleksiyonu yarattığını belirtir. Yani bir koleksiyon üzerinde indeks tanımlamak da onu var etmeye yeter. Bu davranış güncelleme işlemlerinde upsert seçeneğiyle belge eklendiğinde de geçerlidir.

javascript
db.siparisler.insertOne( { no: 1001, durum: "yeni" } )
db.loglar.createIndex( { zaman: 1 } )

2. Açık oluşturma: db.createCollection()

db.createCollection(ad, seçenekler) yöntemi, veritabanı komutu create etrafındaki bir sarmalayıcıdır. Belgeler bu yöntemi esas olarak özel seçenek gerektiren koleksiyonlar için önerir: capped koleksiyonlar, clustered koleksiyonlar, şema doğrulamalı koleksiyonlar ve time series koleksiyonlar. Seçenek vermezseniz örtük oluşturmaya göre bir avantajı yoktur.

javascript
db.createCollection( "musteriler", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: [ "ad", "eposta" ],
      properties: {
        ad: { bsonType: "string" },
        eposta: { bsonType: "string" }
      }
    }
  },
  validationLevel: "strict",
  validationAction: "error"
} )

Bu örnekte musteriler koleksiyonu, ad ve eposta alanlarını zorunlu tutan bir doğrulayıcıyla açılır. validationLevel için "strict" varsayılan değerdir ve kuralları tüm eklemelere ve güncellemelere uygular; "moderate" yalnızca zaten geçerli olan belgelerin güncellemelerini denetler; "off" doğrulamayı kapatır. validationAction ise geçersiz belgede hata mı verileceğini ("error") yoksa sadece uyarı mı yazılacağını ("warn") belirler.

3. Capped koleksiyon

Capped koleksiyonlar sabit boyutludur ve belgeleri eklenme sırasına göre saklar. Ayrılan alan dolduğunda en eski belgeler silinerek yenilerine yer açılır; resmî belge bunu dairesel tampona benzetir. capped: true verdiğinizde bayt cinsinden size zorunludur. İsteğe bağlı max belge sayısı sınırı koyar, ancak size sınırı önceliklidir: boyut sınırına önce ulaşılırsa belge sayısı ne olursa olsun eski belgeler silinir.

javascript
db.createCollection( "olaylar", { capped: true, size: 1048576, max: 2000 } )

createCollection() seçenekleri arasında timeseries (zaman serisi için timeField, metaField, granularity), expireAfterSeconds, clusteredIndex, collation, writeConcern ve görünüm oluşturmaya yarayan viewOn ile pipeline da bulunur. Zaman serileri time series koleksiyonları yazısında, görünümler ise $out, $merge ve görünümler yazısında ele alınıyor.

Aynı adla ikinci kez oluşturursanız

create komutunun belgesine göre, var olan bir koleksiyonu ya da görünümü aynı adla ve birebir aynı seçeneklerle yeniden oluşturmaya çalışırsanız hiçbir işlem yapılmaz ve başarılı yanıt döner. Bu sayede kurulum scriptlerini tekrar tekrar çalıştırmak güvenlidir. Seçenekler farklıysa aynı sonucu beklemeyin; script yazarken koleksiyonun varlığını önceden kontrol etmek daha sağlıklıdır. Ayrıca createCollection() çalıştığı süre boyunca ilgili koleksiyon üzerinde özel (exclusive) bir kilit tutar; bu kilit genellikle kısa sürer ama sonraki işlemler onun bitmesini bekler.

Koleksiyonları listelemek

Mevcut veritabanındaki koleksiyonları görmenin üç yaygın yolu vardır. show collections mongosh yardımcısıdır ve çıktısında bir adın time series koleksiyon mu yoksa salt okunur görünüm mü olduğunu da işaretler. db.getCollectionNames() koleksiyon ve görünüm adlarını bir dizi olarak döndürür; erişim denetimi açıksa yalnızca kullanıcının yetkili olduğu adlar gelir. db.getCollectionInfos() ise listCollections komutunu sarar ve her koleksiyon için ad, tip, seçenekler ve UUID gibi ayrıntıları verir.

javascript
show collections
db.getCollectionNames()
db.getCollectionInfos( { name: "musteriler" } )
db.getCollectionInfos( {}, { nameOnly: true } )

Üçüncü satır yalnızca musteriler koleksiyonunun bilgisini döndürür; burada doğrulayıcı tanımını options içinde görebilirsiniz. Dördüncü satırdaki nameOnly: true seçeneği her koleksiyon için sadece ad ve tip bilgisini getirir. Belgelere göre nameOnly açıkken filtre yalnızca ad ve tip alanlarına göre çalışabilir; başka alanlar kullanılamaz. Ayrıca authorizedCollections: true ile nameOnly: true birlikte verildiğinde, listCollections yetkisi olmayan bir kullanıcı bile erişebildiği koleksiyonların listesini alabilir.

Özel karakterli adlar ve db.getCollection()

Koleksiyona normalde db.urunler biçiminde erişirsiniz. Ancak ad bir alt çizgiyle başlıyorsa, rakamla başlıyorsa, tire gibi özel karakter içeriyorsa ya da bir veritabanı yönteminin adıyla çakışıyorsa bu sözdizimi çalışmaz. Belgelerdeki örnek auth adlı koleksiyondur: db.auth yazdığınızda mongosh bunu db.auth() yöntemi olarak yorumlar ve insertOne çağrısı hata verir. Çözüm db.getCollection("ad") kullanmaktır; dönen nesne db.<ad> ile aynı işlevi görür.

javascript
const kayit = db.getCollection("auth")
kayit.insertOne( { kullanici: "ayse", seviye: 2 } )

db.getCollection("2026-arsiv").find()

İsimlendirme kuralları ve sınırlar

İsimlendirme kuralları ve sınırlar: Veritabanı adı büyük küçük harfle ayrıştırılmaz, Linux ve Unix sistemlerde, Windows sistemlerde, Veritabanı adı

MongoDB'nin sınırlar sayfası veritabanı ve koleksiyon adları için açık kurallar koyar. Bunları bilmek, ileride taşıma ya da yedekten dönme sırasında çıkabilecek sürprizleri önler.

  • Veritabanı adı büyük küçük harfle ayrıştırılmaz: salesData ve SalesData adlı iki veritabanı birlikte bulunamaz. Bir kez oluşturduktan sonra her yerde aynı yazımı kullanmalısınız.
  • Linux ve Unix sistemlerde veritabanı adında /\. "$ karakterleri ve null karakteri bulunamaz.
  • Windows sistemlerde yasak karakter listesi daha uzundur: /\. "$*<>:|? ve null karakteri.
  • Veritabanı adı boş olamaz ve 64 bayttan kısa olmalıdır.
  • Koleksiyon adı alt çizgi ya da harfle başlamalıdır; $ içeremez, boş olamaz, null karakteri içeremez, system. önekiyle başlayamaz (iç kullanım için ayrılmıştır) ve .system. içeremez.
  • Namespace uzunluğu (veritabanı adı, nokta ve koleksiyon adı birlikte) shard edilmemiş koleksiyon ve görünümlerde 255 bayt, shard edilmiş koleksiyonlarda 235 bayttır.

Pratikte en güvenli yol küçük harf, rakam ve alt çizgiyle sınırlı, kısa ve anlamlı adlar seçmektir. Türkçe karakterler UTF-8 olarak birden fazla bayt tutar; uzun ve Türkçe karakterli adlar bayt sınırına beklediğinizden önce yaklaşabilir. Belge düzeyindeki sınırlar da bilinmeli: tek bir BSON belgesi en fazla 16 MiB olabilir ve iç içe yapı 100 seviyeyi geçemez.

Koleksiyonu yeniden adlandırmak

db.collection.renameCollection(hedef, dropTarget) koleksiyonun adını değiştirir ve renameCollection komutunu sarar. İkinci parametre dropTarget varsayılan olarak false'tur; hedef adda bir koleksiyon zaten varsa işlem başarısız olur. true verirseniz hedef koleksiyon önce silinir, bu yüzden dikkatli kullanılmalıdır.

javascript
db.urun_eski.renameCollection("urunler_arsiv")

Bu yöntem koleksiyonu başka bir veritabanına taşıyamaz; bunun için doğrudan renameCollection komutu gerekir. Bir koleksiyonu kendi adına yeniden adlandırmak IllegalOperation hatası verir. İşlem süresince kaynak ve hedef koleksiyon üzerinde özel kilit tutulur. Sürüm notlarına göre MongoDB 9.0 ile time series koleksiyonlar da yeniden adlandırılabilir hale geldi; diğer 9.0 değişiklikleri için MongoDB 9.0 yenilikleri yazısına bakın.

Koleksiyon ve veritabanı silmek

db.collection.drop() koleksiyonu ya da görünümü veritabanından kaldırır ve koleksiyona ait tüm indeksleri de siler. Yöntem true döndürür; belgeler, koleksiyon hiç yoksa bile yine true döndüğünü özellikle not eder. Dolayısıyla dönüş değerine bakarak koleksiyonun gerçekten var olup olmadığını anlayamazsınız.

javascript
db.olaylar.drop()   // çıktı: true

use deneme
db.dropDatabase()

db.dropDatabase() o anda kullandığınız veritabanını, ilişkili veri dosyalarıyla birlikte siler. Bu yüzden komuttan önce db yazıp doğru veritabanında olduğunuzu doğrulamak iyi bir alışkanlıktır. Önemli bir ayrıntı: komut, o veritabanında tanımlı kullanıcıları silmez. Onları da kaldırmak isterseniz aynı veritabanında dropAllUsersFromDatabase komutunu çalıştırmanız gerekir. Replica set üzerinde komut, koleksiyon silmeleri üyelerin çoğunluğuna yayılana kadar en az "majority" write concern ile bekler.

Her iki silme işlemi de, silinen koleksiyon ya da veritabanı üzerinde açık olan change stream'ler için bir invalidate olayı üretir. Uygulamanız change stream dinliyorsa bunu hesaba katın; konu change streams yazısında. Koleksiyonu silmek yerine yalnızca belgeleri temizlemek istiyorsanız farkları deleteOne ve deleteMany yazısında anlatılıyor.

Uygulamalı mini örnek: küçük bir mağaza şeması

Aşağıdaki akış, yeni bir proje için veritabanını hazırlarken izleyebileceğiniz sırayı gösterir. Önce veritabanına geçiyoruz, doğrulama isteyen koleksiyonu açıkça oluşturuyoruz, sıradan koleksiyonları ilk eklemeye bırakıyoruz ve sonunda durumu kontrol ediyoruz.

javascript
use magaza

db.createCollection( "siparisler", {
  validator: { $jsonSchema: { bsonType: "object", required: [ "musteriId", "tutar" ] } }
} )

db.kategoriler.insertMany( [ { ad: "Kırtasiye" }, { ad: "Kitap" } ] )
db.urunler.createIndex( { kategori: 1 } )

show collections
db.getCollectionInfos( {}, { nameOnly: true } )

Bu akışın sonunda siparisler doğrulayıcıyla, kategoriler ilk eklemeyle, urunler ise indeks tanımıyla oluşmuş olur. urunler henüz belge içermese de koleksiyon listesinde yer alır, çünkü createIndex() onu yaratmıştır. Belge ekleme ayrıntıları için insertOne ve insertMany, indeksler için MongoDB index oluşturma yazılarına geçebilirsiniz.

Sık yapılan hatalar

Sık yapılan hatalar: use sonrası veritabanını listede aramak, Yazım hatasıyla yeni koleksiyon yaratmak, Büyük küçük harfi karıştırmak, drop() dönüşüne güvenmek
  • use sonrası veritabanını listede aramak: Veri yazılmadan veritabanı oluşmaz; show dbs çıktısında görünmemesi normaldir.
  • Yazım hatasıyla yeni koleksiyon yaratmak: db.urunlr.insertOne(...) gibi bir yazım hatası sessizce yeni bir koleksiyon açar. Örtük oluşturma kolaylık sağlar ama yazım hatalarını yakalamaz; düzenli olarak show collections ile kontrol edin.
  • Büyük küçük harfi karıştırmak: Magaza ve magaza aynı sunucuda birlikte bulunamaz; tek bir yazım belirleyin.
  • drop() dönüşüne güvenmek: Koleksiyon yokken de true döner; varlık kontrolü için getCollectionNames() kullanın.
  • dropDatabase() ile kullanıcıların da silindiğini sanmak: Kullanıcılar kalır; ayrıca kaldırmanız gerekir.
  • Collation'ı sonradan eklemeye çalışmak: Koleksiyon varsayılan collation'ı oluşturma anında belirlenir.
  • Log için hemen capped koleksiyona yönelmek: Eşzamanlı yazma performansı düşüktür; çoğu durumda TTL indeks daha uygundur.

Sık Sorulan Sorular

Boş bir veritabanı oluşturabilir miyim?

Belgelerdeki yöntem, veritabanının ilk veri saklandığında oluşmasıdır. Pratikte boş görünen bir veritabanı istiyorsanız db.createCollection() ile içi boş bir koleksiyon açabilirsiniz; koleksiyon oluştuğu için veritabanı da oluşmuş olur.

createCollection() kullanmak zorunlu mu?

Hayır. Sadece capped, clustered, time series, doğrulamalı ya da özel collation gerektiren koleksiyonlarda anlamlıdır. Sıradan koleksiyonlar ilk insertOne(), insertMany() veya createIndex() ile kendiliğinden oluşur.

Koleksiyon adında Türkçe karakter kullanabilir miyim?

Kurallar Türkçe harfleri yasaklamaz; yasak olanlar $, null karakteri, boş ad ve system. önekidir. Yine de namespace sınırı bayt üzerinden hesaplandığı ve bazı araçlarda kaçış gerektirebildiği için ASCII harf, rakam ve alt çizgi kullanmak daha az sorun çıkarır.

Koleksiyonu başka bir veritabanına nasıl taşırım?

db.collection.renameCollection() veritabanları arasında taşıma yapmaz. Bunun için yönetici yetkisiyle renameCollection komutunu kullanmanız gerekir. Taşımadan önce yedek almayı unutmayın.

Koleksiyonlar transaction içinde oluşturulabilir mi?

Belgelere göre işlem çapraz shard bir yazma transaction'ı değilse, transaction içinde koleksiyon ve indeks oluşturulabilir; bu durumda transaction "local" read concern kullanmalıdır. Ayrıntılar için MongoDB transaction kullanımı yazısına bakın.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: MongoDB öğrenme rehberi · insertOne ve insertMany · Şema doğrulama · mongosh kullanımı · TTL indeks · Belge silme