MongoDB'de belge eklemek için iki temel yöntem vardır: tek bir belge için db.collection.insertOne(), birden fazla belge için db.collection.insertMany(). İlki eklenen belgenin _id değerini insertedId alanında, ikincisi tüm eklenen belgelerin kimliklerini insertedIds içinde döndürür. Belgede _id yoksa otomatik olarak bir ObjectId atanır; koleksiyon yoksa ilk ekleme onu oluşturur. insertMany() varsayılan olarak sıralı (ordered: true) çalışır ve ilk hatada durur.
Bu yazıda iki yöntemin sözdizimini, dönüş değerlerini, _id alanının kurallarını, sıralı ve sırasız ekleme farkını, hata nesnelerini, toplu eklemelerdeki batch davranışını ve sık yapılan hataları MongoDB 9.0 belgelerine dayanarak anlatıyoruz. Veritabanı ve koleksiyon kavramları için önce veritabanı ve koleksiyon oluşturma yazısına bakabilirsiniz.
insertOne(): tek belge eklemek
insertOne(belge, { writeConcern }) bir koleksiyona tek bir belge ekler. İlk parametre eklenecek belgedir; ikinci parametre isteğe bağlıdır ve yalnızca writeConcern alanını alır. Write concern vermezseniz varsayılan değer kullanılır. Yöntem iki alanlı bir belge döndürür: işlem write concern ile çalıştıysa true, write concern kapatıldıysa false olan acknowledged ve eklenen belgenin kimliğini taşıyan insertedId.
use magaza
db.urunler.insertOne( {
ad: "Defter",
fiyat: 45,
etiketler: [ "kırtasiye", "okul" ],
boyut: { en: 17, boy: 24, birim: "cm" }
} )
// çıktı: { acknowledged: true, insertedId: ObjectId("569525e144fe66d60b772763") }Belgede _id olmadığı için sunucu bir ObjectId üretip belgeye ekler. Çıktıdaki ObjectId resmî belgelerdeki örnek değerdir; belgelerin de belirttiği gibi ObjectId, işlemin çalıştığı makineye ve zamana göre üretildiğinden sizin göreceğiniz değer farklı olacaktır. Görüldüğü gibi bir belge iç içe belgeler (boyut) ve diziler (etiketler) içerebilir; bunları ayrıca tanımlamanıza gerek yoktur.
Eklediğiniz belgeyi geri okumak için find() kullanabilirsiniz. mongosh belgeleri, tam olarak eklediğiniz belgeyi bulmak istiyorsanız başlık gibi bir alan yerine _id ile sorgulamanızı önerir; çünkü aynı başlıklı başka belgeler de olabilir. Sorgu ayrıntıları find sorguları yazısında.
const sonuc = db.urunler.insertOne( { ad: "Silgi", fiyat: 10 } )
db.urunler.findOne( { _id: sonuc.insertedId } )insertMany(): birden fazla belge eklemek
insertMany([belge1, belge2, ...], { writeConcern, ordered }) bir dizi belgeyi tek çağrıda ekler. Dönüş belgesinde yine acknowledged bulunur, ayrıca başarıyla eklenen her belgenin _id değerini içeren insertedIds yer alır. Belgelere göre dizide verebileceğiniz belge sayısının bir üst sınırı yoktur; büyük diziler arka planda parçalara bölünür (aşağıda batch bölümüne bakın).
db.urunler.insertMany( [
{ ad: "Kurşun kalem", fiyat: 8 },
{ ad: "Cetvel", fiyat: 20 },
{ ad: "Pergel", fiyat: 75 }
] )
// çıktı:
// {
// acknowledged: true,
// insertedIds: [
// ObjectId("562a94d381cb9f1cd6eb0e1a"),
// ObjectId("562a94d381cb9f1cd6eb0e1b"),
// ObjectId("562a94d381cb9f1cd6eb0e1c")
// ]
// }Çıktının biçimi insertMany() belgesindeki örnekten alınmıştır; ObjectId değerleri sizde farklı olur. Üç belgenin hiçbirinde _id olmadığından sunucu üçüne de ayrı ObjectId atar.
_id alanı: kurallar ve seçenekler

Standart bir koleksiyonda saklanan her belge, birincil anahtar görevi gören benzersiz bir _id alanına ihtiyaç duyar. Eklediğiniz belgede bu alan yoksa çoğu sürücü ObjectId'yi istemci tarafında üretip gönderir; istemci üretmezse mongod kendisi ekler. Aynı kural upsert: true ile yapılan güncellemelerin eklediği belgeler için de geçerlidir (bkz. updateOne ve updateMany).
_iddeğeri koleksiyonda benzersiz olmalıdır ve sonradan değiştirilemez.- MongoDB koleksiyon oluşturulurken
_idüzerinde benzersiz bir indeksi varsayılan olarak kurar. _idher zaman belgenin ilk alanıdır; başka bir yerde gönderirseniz sunucu onu başa taşır.- Dizi, regex ve undefined dışındaki her BSON tipini alabilir. Belgeler, replikasyonun düzgün çalışması için regex tipini
_id'de saklamamanızı ayrıca uyarır. _idalt alanlar içeren bir belge ise alt alan adları$ile başlayamaz.
_id için yaygın seçenekler şunlardır: ObjectId kullanmak, varsa doğal bir benzersiz tanımlayıcıyı (örneğin ürün kodunu) kullanmak, otomatik artan bir sayı üretmek ya da uygulamada UUID üretmek. Belgeler doğal anahtarın yer tasarrufu sağladığını ve ek bir indeks gereğini ortadan kaldırdığını belirtir. UUID kullanacaksanız daha verimli saklama için BSON BinData tipinde tutulmasını önerir. ObjectId'nin yapısı ve diğer tipler için BSON veri tipleri yazısına bakın.
db.urunler.insertOne( { _id: "KLM-001", ad: "Dolma kalem", fiyat: 320 } )
db.urunler.insertMany( [
{ _id: "KLM-002", ad: "Tükenmez kalem", fiyat: 12 },
{ _id: "KLM-003", ad: "Uçlu kalem", fiyat: 35 }
] )Bu örneklerde kimliği biz verdiğimiz için dönüşteki insertedId ve insertedIds alanları ObjectId yerine verdiğimiz metin değerleri taşır. Kimliği kendiniz verdiğinizde benzersizlik sorumluluğu da sizdedir.
Yinelenen _id ve E11000 hatası
_id ya da başka bir benzersiz indeksin parçası olan alana var olan bir değeri yeniden yazmaya çalışırsanız işlem hata fırlatır. insertOne() bu durumda bir WriteError üretir; belgelerdeki örnek hatada code değeri 11000 olup mesaj E11000 duplicate key error ile başlar ve çakışan koleksiyonu, indeks adını (_id_) ve yinelenen anahtarı gösterir. mongosh'ta hatayı programatik olarak yakalamak için çağrıyı try/catch içine almanız yeterli.
try {
db.urunler.insertOne( { _id: "KLM-001", ad: "Yinelenen kayıt" } )
} catch (e) {
print(e)
}Bu kod KLM-001 zaten var olduğu için ekleme yapmaz ve hata nesnesini yazdırır. Hatanın tüm nedenleri (unique indeksler, upsert yarışları) ve çözümleri için E11000 duplicate key hatası yazısına bakın.
ordered: true ve ordered: false farkı

insertMany() belgeleri varsayılan olarak verdiğiniz sırayla ekler. ordered seçeneği hata anındaki davranışı belirler:
- ordered: true (varsayılan): Bir ekleme başarısız olursa sunucu kalan belgeleri eklemeye devam etmez. Hatalı belgeden önceki belgeler koleksiyonda kalır; sonrakiler eklenmez.
- ordered: false: Bir ekleme başarısız olsa bile sunucu kalan belgeleri eklemeyi sürdürür. Bu modda
mongodperformans için belgelerin sırasını değiştirebilir; uygulamanız ekleme sırasına güvenmemelidir.
try {
db.urunler.insertMany( [
{ _id: "KLM-010", ad: "Fosforlu kalem" },
{ _id: "KLM-001", ad: "Çakışan kayıt" },
{ _id: "KLM-011", ad: "Keçeli kalem" }
], { ordered: false } )
} catch (e) {
print(e)
}Bu örnekte ikinci belgenin _id değeri zaten var. ordered: false verdiğimiz için KLM-010 ve KLM-011 eklenir, yalnızca çakışan belge reddedilir. Aynı çağrıyı seçenek olmadan (yani sıralı) çalıştırsaydınız KLM-010 eklenir, hata ikinci belgede oluşur ve KLM-011 hiç denenmezdi.
Belgelere göre insertMany() hata durumunda bir BulkWriteError fırlatır. Write concern hataları writeConcernErrors alanında, diğer tüm hatalar writeErrors alanında listelenir. Hata oluştuğunda eklenen kimliklerin listesi yerine başarılı işlem sayısı (nInserted gibi) gösterilir. Sıralı işlem karşılaştığı tek hatayı, sırasız işlem ise oluşan her hatayı dizi halinde raporlar. Her hata kaydındaki index, code, errmsg ve op alanları sorunlu belgeyi bulmanızı kolaylaştırır.
| Durum | ordered: true | ordered: false |
|---|---|---|
| Hata sonrası kalan belgeler | Eklenmez | Eklenmeye devam eder |
| Ekleme sırası | Verilen sıra | Sunucu değiştirebilir |
| Raporlanan hata | Karşılaşılan tek hata | Tüm hatalar dizi olarak |
| Uygun kullanım | Sıranın önemli olduğu işler | Bağımsız kayıtların toplu yüklenmesi |
Batch sınırı ve büyük yüklemeler
insertMany() dizisindeki belgeler sürücü tarafından maxWriteBatchSize değerine göre parçalara ayrılır. Bu değer 100.000'dir ve değiştirilemez. Belgelerdeki örneğe göre 250.000 belgelik bir insertMany() çağrısı, ikisi 100.000 ve biri 50.000 belgelik üç batch olarak gönderilir. Bu bölme yalnızca üst düzey API kullanıldığında yapılır; db.runCommand() ile doğrudan insert komutu gönderirseniz sınırı aşan bir batch hata ile sonuçlanır.
Tek bir batch'in hata raporu çok büyürse MongoDB kalan hata mesajlarını kısaltır. Belgeler, bu boyut ve gruplama ayrıntılarının iç performans konuları olduğunu ve ileriki sürümlerde değişebileceğini not eder. Yani uygulama mantığınızı bu iç sayılara bağlamayın. Rastgele değerli alanlara sahip çok sayıda belge eklerken indeks performansının düşebileceği de belgelerde belirtilir: rastgele indeks girdileri indeksi büyütür ve indeks önbelleğe sığmaz hale gelince WiredTiger önbelleğinde sık yer değiştirme yaşanır. Belgelerin önerdiği iki çözüm, indeksi silip veriyi ekledikten sonra yeniden oluşturmak ya da veriyi indekssiz boş bir koleksiyona eklemektir. İndeks konusu MongoDB index oluşturma yazısında ele alınıyor. Ekleme, güncelleme ve silmeyi tek çağrıda karıştırmak istiyorsanız bulkWrite toplu işlemler yazısına geçin.
Write concern ile onay seviyesi
Her iki yöntem de ikinci parametrede writeConcern belgesi alır. Örneğin üç üyeli bir replica set'te { w: "majority", wtimeout: 100 } vermek, yazmanın çoğunluk tarafından onaylanmasını bekler. Onay belirtilen süreden uzun sürerse işlem bir WriteConcernError fırlatır; belgelerdeki örnekte bu hatanın code değeri 64'tür. Bu hata yazmanın geri alındığı anlamına gelmez, yalnızca istenen onayın zamanında gelmediğini gösterir. Seviyelerin ayrıntısı write concern ve read concern yazısında.
db.urunler.insertOne(
{ ad: "Zımba", fiyat: 90 },
{ writeConcern: { w: "majority", wtimeout: 100 } }
)Transaction içinde çalışırken işleme özel bir write concern vermeyin; belgeler write concern'in transaction düzeyinde ayarlanması gerektiğini belirtir. Transaction içinde var olmayan bir koleksiyona ekleme yapılırsa koleksiyon örtük olarak oluşturulur (çapraz shard yazma transaction'ı değilse). Ayrıntılar transaction kullanımı yazısında.
Atomiklik, alan sırası ve diğer davranışlar
MongoDB'de yazma işlemleri tek bir belge düzeyinde atomiktir. Bu, insertMany() çağrısının bütün olarak atomik olmadığı anlamına gelir: sıralı modda bile hatadan önce eklenen belgeler geri alınmaz. Birden fazla belgenin ya hep ya hiç yazılması gerekiyorsa transaction kullanmalısınız.
BSON belgelerinde alanlar sıralıdır ve yazma işlemlerinde MongoDB verdiğiniz alan sırasını korur; iki istisna vardır: _id her zaman ilk alandır ve $rename içeren güncellemeler alanların sırasını değiştirebilir. Ayrıca her iki ekleme yöntemi de db.collection.explain() ile uyumlu değildir; yani ekleme işlemleri için sorgu planı alamazsınız. Başarılı bir insertOne() oplog'a bir kayıt ekler; insertMany() ise birden fazla belgeyi oplog'da tek bir kayıt altında birleştirir. Başarısız işlemler oplog'a yazılmaz.
Belge boyutu sınırını da unutmayın: tek bir BSON belgesi en fazla 16 MiB olabilir. Daha büyük dosyalar için belgeler GridFS API'sini gösterir. Alan adlarında null karakteri bulunamaz ve bir belgede aynı alan adı iki kez yer almamalıdır; yinelenen alanlar CRUD işlemlerinde beklenmedik davranışa yol açabilir.
Eski insert() yöntemi

Eski mongo kabuğundan kalma db.collection.insert() mongosh'ta kullanımdan kaldırılmış (deprecated) olarak işaretlenmiştir. mongosh uyumluluk sayfası yerine insertOne(), insertMany() veya bulkWrite() kullanmanızı önerir. Aynı şekilde save() yöntemi de kullanımdan kaldırılanlar arasındadır. Eski örneklerde bu yöntemleri görürseniz yeni karşılıklarına çevirin.
| Yöntem | Ne ekler | Dönüş alanı | Durum |
|---|---|---|---|
| insertOne() | Tek belge | insertedId | Önerilen |
| insertMany() | Belge dizisi | insertedIds | Önerilen |
| bulkWrite() | Karışık yazma işlemleri | İşlem sayıları | Önerilen |
| insert() | Tek veya çok belge | Eski biçim | Kullanımdan kaldırıldı |
Sık yapılan hatalar
- insertMany() çağrısına dizi yerine tek belge vermek: Yöntem bir belge dizisi bekler; tek belge için
insertOne()kullanın. - Seçenekleri yanlış yere yazmak:
orderedvewriteConcernikinci parametredeki seçenek belgesine yazılır, dizinin içine değil. - Sıralı modda kısmi eklemeyi gözden kaçırmak: Hata aldığınızda hatadan önceki belgeler eklenmiş olabilir; yeniden denemeden önce hangi belgelerin yazıldığını kontrol edin, yoksa bu kez onlar E11000 verir.
- ordered: false ile sıra beklemek: Sunucu belgeleri yeniden sıralayabilir.
- Kendi _id değerini verip benzersizliği denetlememek: Özellikle dış sistemden gelen kodlarda yinelenen değerler toplu yüklemeyi yarıda keser.
- insertMany() sonucunu atomik sanmak: Atomiklik belge düzeyindedir; hep ya hiç için transaction gerekir.
- Yazım hatalı koleksiyon adı: Ekleme var olmayan koleksiyonu sessizce oluşturur; adı kontrol edin.
Sık Sorulan Sorular
insertOne() ile insertMany() arasında performans farkı var mı?
Belgeler bir hız karşılaştırması vermez. Bildiğimiz şey, insertMany() belgelerin tek çağrıda gönderilmesini ve sürücü tarafından 100.000'lik batch'lere bölünmesini sağladığıdır. Çok sayıda belgeyi tek tek insertOne() ile göndermek her biri için ayrı istek demektir.
Eklenen belgenin _id değerini nasıl alırım?
insertOne() dönüşündeki insertedId, insertMany() dönüşündeki insertedIds alanını okuyun. Bu değerleri bir değişkene atayıp hemen findOne() ile sorgulayabilirsiniz.
Koleksiyon yoksa insertOne() hata verir mi?
Hayır. Koleksiyon yoksa ekleme işlemi onu oluşturur. Özel seçenekli bir koleksiyon gerekiyorsa önce db.createCollection() çalıştırın.
Toplu eklemede bir belge hatalıysa ne olur?
Varsayılan sıralı modda işlem o belgede durur, önceki belgeler kalır. ordered: false verirseniz kalan belgeler eklenmeye devam eder ve tüm hatalar writeErrors içinde raporlanır.
Ekleme işlemini explain() ile inceleyebilir miyim?
Hayır, belgelere göre insertOne() ve insertMany() db.collection.explain() ile uyumlu değildir. Sorgu planları için explain ve sorgu planı 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 · Veritabanı ve koleksiyon oluşturma · find sorguları · bulkWrite · E11000 hatası · BSON veri tipleri