1. MongoDB nedir?
MongoDB document tabanlı, yüksek performans, yüksek kullanılabilirlik ve otomatik scaling sunan C++ ile yazılmış açık kaynak bir veritabanıdır.
Document Data Type
- MongoDB verileri Document (BSON Binary JSON) formatında tutar. BSON JSON formatına çok benzerdir.
- BSON'un avantajları:
- Birçok programlama dilinde kullanılır.
- Gömülü belgeler ve diziler join ihtiyacını azaltır.
- Dinamik şema yapısını destekler.
- BSON'un avantajları:
2. Temel Özellikler
1. Rich Query Language
- Data Aggregation
- Text Search
- Geospatial (Coğrafi) Queries
2. High Availability
- Otomatik yük dağılımı
- Veri yedekleme
3. Yatay Genişleme
- Sharding mimarisi ile veriyi cluster'lara dağıtma
- Zone denilen bölgeleri oluşturma
4. Birden fazla Depolama Motorları desteği
- WiredTiger Storage Engine
- In-Memory Storage Engine
- MMAPv1 Storage Engine
3. Detaylar
1. Rich Query Language
- MLab ile online mongodb oluşturulur.
- Robomongo Studio 3T indirilir.
- testdata.json import edilir.
MongoDB Crud Operations
1.- Insert:
- insert: Bir veya birden çok kayıt ekler
- insertOne: Bir kayıt ekler
- insertMany: Birden çok kayıt ekler
db.artwork.insertOne( { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } } )
- Query:
- find: Query yapmamızı sağlar
db.inventory.find( {} )
=>SELECT * FROM inventory
- Update:
- updateOne: Bir kaydı günceller
- updateMany: Birden çok kaydı günceller
- replaceOne: _id field'ı dışındaki field'ları yeniden oluşturur, _id field'ı immutable (değiştirilemez) 'dır.
* update db.artwork.updateOne( { _id: 2 }, { $set: { status: "P" }, $currentDate: { lastModified: true } } ) db.artwork.find({ _id: 2 })
- replaceOne:
db.inventory.find({ item: "paper" }) db.inventory.replaceOne( { item: "paper" }, { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] } ) db.inventory.find({ item: "paper" })
- Delete:
- delete: Bir veya birden çok kaydı siler
- deleteOne: Bir kaydı siler
- deleteMany: Birden çok kaydı siler
- Retryable Writes: MongoDB bir yazma işleminde network hatası oluşursa yazma işlemini tekrar deneyebilir.
Text Search
2.- Text Search yapabilmemiz için istediğimiz field'ları index'lememiz gerekir.
db.stores.createIndex( { name: "text", description: "text" } )
- Arama index'lediğimiz tüm alanlarda gerçekleşir.
db.stores.find( { $text: { $search: "coffee" } } )
- Or:
// java, coffee veya shop olanlar
db.stores.find( { $text: { $search: "java coffee shop" } } )
- Exact:
// Exact arama için kelime "" içine alınmalı
// java veya coffee shop olanlar
db.stores.find( { $text: { $search: "java \"coffee shop\"" } } )
- Term Exclusion:
// java veya shop olan ama coffee olmayan
db.stores.find( { $text: { $search: "java shop -coffee" } } )
- Text Search Türkçe dahil pek çok dili destekler. Diller
3. Data Models
- Döküman Yapısı MongoDB filexible schema özelliğine sahiptir yani aynı dökümanda bir kayıt bir kayıttan farklı olabilir. MongoDB'de 2 tür döküman yapısı bulunur.
- Schema Validation (3.6'dan sonra)
- MongoDB update ve insert işleminden önce schema validation işlemini yapabilir.
db.createCollection("students", { validator: { $jsonSchema: { bsonType: "object", required: [ "name", "year", "major", "gpa"], properties: { name: { bsonType: "string", description: "must be a string and is required" }, gender: { bsonType: "string", description: "must be a string and is not required" }, year: { bsonType: "int", minimum: 2017, maximum: 3017, exclusiveMaximum: false, description: "must be an integer in [ 2017, 3017 ] and is required" }, gpa: { bsonType: [ "int" ], description: "must be a integer and is required" } } } } })
db.students.insert({ name: "Alice", year: NumberInt(2019), major: "History", gpa: NumberLong(3) })
4. Aggregation
- Agrregation SQL karşılıkları için link.
- MongoDB'nin Aggregation işlemleri Stage'lerden oluşan "data processing pipeline" üzerine dayalıdır. Bir Collection stage'ler arasında taşınarak işlenir. Aggregation işlemlerinde Aggregation Pipeline operatörlerini de kullanabiliriz. Operatörler.
- $match:
db.testdata.aggregate([ { $match: { "zip": 90210 }} ])
- $group:
db.testdata.aggregate([ { $match: {"zip": 90210}}, { $group: { _id: null, count: { $sum: 1 } } } ]);
- $sort:
db.testdata.aggregate([ { $group : {_id : "$hosting", total : { $sum : 1 }} }, { $sort : {total : -1} } ]);
- $addFields:
- Result'a yeni bir field ekler.
db.scores.aggregate( [ { $addFields: { totalHomework: { $sum: "$homework" } , totalQuiz: { $sum: "$quiz" } } }, { $addFields: { totalScore: { $add: [ "$totalHomework", "$totalQuiz", "$extraCredit" ] } } } ])
- $unwind:
- Verideki array'i parçalayarak her bir değeri yeni bir satır olarak gösterir.
db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
- $bucket:
- Dökümanları expression'lara göre gruplara ayırır.
- output kısmında belirtilen her bucket bir döküman gibi ele alınır.
- $bucket groupBy ifadesine göre dökümanları gruplama yaparak _id alanında bu değeri gösterir. groupBy ifadesinde göre işlenen bucket'lar boundaries (sınırlar) kısmında sınırları belirtilir.
db.artwork.aggregate( [ { $bucket: { groupBy: "$price", boundaries: [ 0, 200, 400 ], default: "Other", output: { "count": { $sum: 1 }, "titles" : { $push: "$title" } } } } ] )
- $facet:
- $bucket birden fazla bucket işlemini tek bir sorguda yapabilmemizi sağlar.
db.artwork.aggregate( [ { $facet: { "categorizedByTags": [ { $unwind: "$tags" }, { $sortByCount: "$tags" } ], "categorizedByPrice": [ // Filter out documents without a price e.g., _id: 7 { $match: { price: { $exists: 1 } } }, { $bucket: { groupBy: "$price", boundaries: [ 0, 150, 200, 300, 400 ], default: "Other", output: { "count": { $sum: 1 }, "titles": { $push: "$title" } } } } ], "categorizedByYears(Auto)": [ { $bucketAuto: { groupBy: "$year", buckets: 4 } } ] } } ])
- $graphLookup:
- Hiyerarşik yapıda tutulan veriyi denormalize (hiyerarşisi çözülmüş halde) şekilde gösterir.
- Order ve Product ilişkisini gösteren örnek:
db.orders.aggregate([ { $lookup: { from: "products", localField: "product_ids", foreignField : "_id", as: "ordered_product" } } ])
- $lookup:
db.orders.aggregate([ { $unwind: "$product_ids" }, { $lookup: { from: "products", localField: "product_ids", foreignField : "_id", as: "ordered_product" } } ])
- $collStats:
- Bir collection veya view ile ilgili istatistikleri verir.
db.artwork.aggregate( [ { $collStats: { storageStats: { } } } ] )
- $out:
- Oluşturulan sonucu ayrı bir dökümana yazar. Eğer o döküman varsa onu değiştirir.
- Her zaman son stage olmalıdır.
db.books.aggregate( [ { $group : { _id : "$author", books: { $push: "$title" } } }, { $out : "authors" } ] )
- $project:
- İstenilen field'ları bir sonraki stage'e taşır. Field'ların çıkarılması (exclude) veya içerilmesi (include) sağlanabilir.
// Include: Sadece Title ve Author db.books.aggregate( [ { $project : { title : 1 , author : 1 } } ] )
// Exclude: Title dışında herşey db.books.aggregate( [ { $project : { title : 0} } ] )
- $redact:
- İç içe olan dökümanlarda istenilen ifadeye göre kısıtlamalar yapar.
// Sadece STLW ve G olan olan iç dökümanlar listelenir diğerleri kısıtlanır. var userAccess = [ "STLW", "G" ]; db.forecasts.aggregate( [ { $match: { year: 2014 } }, { $redact: { $cond: { if: { $gt: [ { $size: { $setIntersection: [ "$tags", userAccess ] } }, 0 ] }, then: "$$DESCEND", else: "$$PRUNE" } } } ] );
db.accounts.aggregate( [ { $match: { status: "A" } }, { $redact: { $cond: { if: { $eq: [ "$level", 5 ] }, then: "$$PRUNE", // budar else: "$$DESCEND" } } } ] );
- $replaceRoot:
- Yeni kök dökümanın hangisi olduğunu belirler.
db.produce.aggregate( [ { $replaceRoot: { newRoot: "$in_stock" } } ] )
Map Reduce
4.MongoDB Map-Reduce işlemiyle JavaScript dilinde yazdığımız koda göre verileri getirir.
- Map: Key-Value şeklinde istenilen field'lar alınır.
- Reduce: Alınan field'lar analitik işlemlere tabi tutularak filtrelenir.
- Map-Reduce işlemiyle sonuçları bir koleksiyona yazabiliriz.
- Dönen sonuç 16MB'dan büyük olmamalıdır.
// Map var mapFunction1 = function() { emit(this.cust_id, this.price); }; // Reduce var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); }; // Sonuç map_reduce_example dökümanına yazılır db.ordersmapreduce.mapReduce( mapFunction1, reduceFunction1, { out: "map_reduce_example" } )
Query Modifiers
5.- $explain:
db.artwork.find().explain()
- $hint:
- Query Optimizer için belirli bir field'ın kullanılmasını zorunlu kılar.
db.users.find().hint( { age: 1 } )
- $maxScan :
- Query'nin oluşturulmasında ne kadar dökümanın taranacağını kısıtlar.
Sharding
5.- Sharding veriyi makineler üzerine dağıtma yöntemidir.
Sistemi büyütmek için ya Vertical (dikey) Scaling ya da Horizontal (yatay) Scaling yapmamız gerekir. Sharding yatay genişlemede kullanılır.
- Bir Sharded Cluster şu bileşenleri taşır. 147
- Shard: Her shard sharded data'nın bir alt kümesini taşır.
- Mongos: Client application ve Cluster arasında olan Query router arayüzüdür.
- Config Servers
// Todo: Sharding işlemleri