Azure Üzerinde Cosmos DB İle CRUD
Selamlar,
Bu makalede Azure CosmosDB’yi beraberce inceleyeceğiz. CosmosDB “Database as a Service” yani Azure’da hizmet olarak sunulan tek şey, sadece Database’dir. Azure Cosmos DB, Microsoft’un NoSQL veri tabanlarının hizmet karşılığı olarak düşünülebilir. Yani (DaaS). En önemli özelliği, Sql gibi sorgulama yapılabilmesi ve nosql gibi çok hızlı result dönebilmesidir.
Azure üzerinde “Azure Cosmos DB” şeklinde bir aram yapıldığında, aşağıdaki gibi bir ekran ile karşılaşılır.
Daha sonra aşağıdaki gibi bir ekran ile isimlendirilir ve oluşturulur. API olarak bu uygulamada Core(SQL) seçilmiştir. Bunun dışında Azure Cosmos DB, 5 farklı API desteklemektedir: Core(SQL) document database, Gremlin graph database, MongoDB document databases, Azure Table ve Cassandra.
Bu örnekte Core(SQL) seçilmesinin nedeni document, database ve query’nin SQL syntax’ı ile oluşturulmak istenmesidir.
Son adım olarak karşımıza aşağıdaki gibi bir ekran gelir: Validate işlemi tamamlandıktan sonra, “Create” button’lna basılarak CosmosDB Azure üzerinde oluşturulmuş olunur.
İlgili database oluştuğu zaman, Azure’da karşımıza aşağıdaki gibi bir ekran çıkmaktadır:
Cosmos DB’ye dışardan erişim, Keys alanındaki “Url” ve “Primary Key” alanları ile yapılmaktadır.
Sıra geldi, Cosmos DB’ye bağlanmaya. Öncelikle Visual Studio 2017 ile .Net Console Application yaratılır.
Manage Nuget Packages’dan ==> “Microsoft.Azure.DocumentDB” aşağıdaki gibi indirilir.
1-) Aşağıdaki kütüphaneler sayfaya eklenir.
1 2 3 4 |
using System.Net; using Microsoft.Azure.Documents; using Microsoft.Azure.Documents.Client; using Newtonsoft.Json; |
2-) Aşağıdaki tanımlamalar, Azure CosmosDB’ye bağlanmak için yapılır. EndPoint : “CosmosDB Url’i”, PrimaryKey : “CosmosDB key’i” dir. Bu değerler, Azure üzerinden yukarıda belirtildiği gibi alınabilir.
1 2 3 4 5 6 7 |
class Program { private const string EndpointUrl = "<your endpoint URL>"; private const string PrimaryKey = "<your primary key>"; private DocumentClient client; static void Main(string[] args) |
Program.cs: Eğer DB yok ise CustomerDB adında bir Database ve Collection yaratılıp, kayıt amaçlı bir döküman ilgili CosmosDB’ye kaydedilecektir.
- “CreateDB()” :Tüm işlemin yapıldığı asenkron methoddur.
- “using (client = new DocumentClient(new Uri(EndpointUrl), PrimaryKey))” : Azure CosmosDB’ye bağlanılır.
- “await client.CreateDatabaseIfNotExistsAsync(new Database { Id = “CustomerDB” })” : Eğer CustomerDB yok ise oluşturulur.
- “await client.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri(“CustomerDB”), new DocumentCollection { Id = “CustomerCollection” })” : Eğer yok ise CustomerDB’ye ait Collection oluşturulur.
- “Customer bora = new Customer” : Database’e atılacak kayıt yani Document oluşturulur.
- “await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(“CustomerDB”, “CustomerCollection”), bora)”: “bora” adında oluşturulan Document yani kayıt, CustomerDB CosmosDB’si ve CustomerCollection’ına atılır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using Microsoft.Azure.Documents; using Microsoft.Azure.Documents.Client; using Newtonsoft.Json; namespace GetDataCosmosDB { class Program { private const string EndpointUrl = "https://newsdata.documents.azure.com:443/"; private const string PrimaryKey = "xxxxxxxxxxxxxx"; private static DocumentClient client; static void Main(string[] args) { try { CreateDB().Wait(); } catch (Exception ex) { Console.WriteLine("Error:" + ex.Message); } async Task CreateDB() { using (client = new DocumentClient(new Uri(EndpointUrl), PrimaryKey)) { //Create DB await client.CreateDatabaseIfNotExistsAsync(new Database { Id = "CustomerDB" }); //Create Collection await client.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri("CustomerDB"), new DocumentCollection { Id = "CustomerCollection" }); // Add Document Customer bora = new Customer { Id = "34", LastName = "Kasmer", Children = new Child[] { new Child { FamilyName="Kasmer", FirstName = "Duru", Gender = "female", Age = 7, Address = new Address { State = "Marmara", County = "Türkiye", City = "İstanbul" }, } }, GSM = "05326837118", TCKN = "12366734800" }; await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri("CustomerDB", "CustomerCollection"), bora); } } } } } |
CosmosDB’ye, yeni bir document aşağıdaki gibi eklenir. Aslında her bir document, yeni bir kayıt anlamına gelmektedir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Add Document2 Customer murat = new Customer { Id = "48", LastName = "Durmaz", Children = new Child[] { new Child { FamilyName="Durmaz", FirstName = "Murat", Gender = "male", Age = 23, Address = new Address { State = "Fethiye", County = "Türkiye", City = "Muğla" }, } }, GSM = "05442436789", TCKN = "3704495678" }; await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri("CustomerDB", "CustomerCollection"), murat); |
2. kayıdın eklenmesinden sonra, azure üzerindeki Documentlerin son durumu aşağıdaki gibidir: İlgili documentler, “id” değerlerine göre sıralanmaktadır.
Customer.cs : CosmosDB’ye atılacak Customer Document’dir. Modeli aşağıdaki gibidir. “Customer” ==> Customer’a ait “Children” ==> Ve son olarak Children’a ait “Address” modelleri, aşağıdaki gibi tanımlanmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GetDataCosmosDB { class Customer { [JsonProperty(PropertyName = "id")] public string Id { get; set; } public string LastName { get; set; } public string GSM { get; set; } public Child[] Children { get; set; } public string TCKN { get; set; } public override string ToString() { return JsonConvert.SerializeObject(this); } } public class Child { public string FamilyName { get; set; } public string FirstName { get; set; } public string Gender { get; set; } public int Age { get; set; } public Address Address { get; set; } } public class Address { public string State { get; set; } public string County { get; set; } public string City { get; set; } } } |
Azure Üzerindeki CosmosDB Sorguları: İlk Customer “bora” Document Azure CosmosDB’ye atıldıktan sonra, “select * from c where c.id =”34″” şeklindeki sorgunun sonucu aşağıdaki gibidir.
Sorgu 2: Aşağıdaki sorguda, çocuğunun isim Murat olan kayıt getirilmektedir. “Görüldüğü gibi NoSql bir DB üzerinde Sql sorgusu yapılabilmektedir” :)
1 2 |
SELECT * FROM c JOIN ch IN c.Children where ch.FirstName = 'Murat' |
Sonuç: Aşağıdaki gibidir.
Sorgu 3: Aşağıdaki sorguda, çocuğunun ülkesi ‘Türkiye’ olan 2 kayıt bulunmaktadır.
1 2 |
SELECT * FROM c JOIN ch IN c.Children where ch.Address.County = 'Türkiye' |
Sonuç: Aşağıdaki gibidir.
Şimdi gelin Query’i, Console uygulama üzerinde yapalım: Aşağıdaki query’de, soy ismi “Kasmer” olan kayıtlar listelenir.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 }; IQueryable<Customer> filterCustomer = client.CreateDocumentQuery<Customer>( UriFactory.CreateDocumentCollectionUri("CustomerDB", "CustomerCollection"), queryOptions) .Where(cus => cus.LastName == "Kasmer"); foreach(Customer cus in filterCustomer) { Console.WriteLine($"Customer Id:{cus.Id} - First -Children : {cus.Children.First().FirstName} - Last Name:{cus.LastName} - GSM:{cus.GSM}"); } Console.ReadLine(); |
Ekran çıktısı aşağıdaki gibidir:
Bu örnekde Custom yani sorguya özel bir query result alınacaktır. Bunun için öncelikle aşağıdaki gibi “custome result model” oluşturulur:
QueryCustomer.cs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GetDataCosmosDB { class QueryCustomer { public string Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string GSM { get; set; } } } |
Customer Join Query: Aşağıda görüldüğü gibi Customer ve Child tabloları, joinlenmiş ve geri dönülecek result için “QueryCustomer” adında Custom Result Model oluşturulmuştur.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 }; IQueryable<QueryCustomer> filterCustomer = client.CreateDocumentQuery<QueryCustomer>( UriFactory.CreateDocumentCollectionUri("CustomerDB", "CustomerCollection"), "SELECT c.Id,ch.FirstName,c.LastName,c.GSM FROM c JOIN ch IN c.Children where ch.FirstName = 'Murat' ", queryOptions); foreach(QueryCustomer cus in filterCustomer) { Console.WriteLine($"Customer Id:{cus.Id} - First -Children : {cus.FirstName} - Last Name:{cus.LastName} - GSM:{cus.GSM}"); } Console.ReadLine(); |
Ekran çıktısı aşağıdaki gibidir:
Customer Join Query 2: Aşağıdaki sorguda çocuğunun adresinden ülkesi Türkiye olan kayıtlar listelenmiştir. Gene dönüş tipi “QueryCustomer“‘dır.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 }; IQueryable<QueryCustomer> filterCustomer = client.CreateDocumentQuery<QueryCustomer>( UriFactory.CreateDocumentCollectionUri("CustomerDB", "CustomerCollection"), "SELECT c.Id,ch.FirstName,c.LastName,c.GSM FROM c JOIN ch IN c.Children where ch.Address.County = 'Türkiye' ", queryOptions); foreach(QueryCustomer cus in filterCustomer) { Console.WriteLine($"Customer Id:{cus.Id} - First -Children : {cus.FirstName} - Last Name:{cus.LastName} - GSM:{cus.GSM}"); } Console.ReadLine(); |
Ekran çıktısı aşağıdaki gibidir:
Cosmos DB’de Güncelleme :
- Aşağıdaki örnekde “CreateDocumentQuery<Customer>” Id’si “34” olan kayıt çekilmiştir.
- querydoc.GSM = “0555 555 5555” : Kaydın GSM numarası değiştirilmiştir.
- var result = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(“CustomerDB”, “CustomerCollection”, querydoc.Id), querydoc).Result.Resource : Güncellenen Document, CosmosDB’de güncellenir.
- “Console.WriteLine($”Update document Type :{ result.GetPropertyValue<string>(“GSM”)}”)” : İlgili kayda ait güncellenmiş son GSM değeri, ekrana basılır.
1 2 3 4 5 6 7 8 9 10 11 12 |
var querydoc = client.CreateDocumentQuery<Customer>( UriFactory.CreateDocumentCollectionUri("CustomerDB", "CustomerCollection")) .Where(x => x.Id == "34") .AsEnumerable() .First(); querydoc.GSM = "0555 555 5555"; var result = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri("CustomerDB", "CustomerCollection", querydoc.Id), querydoc).Result.Resource; Console.WriteLine(result); Console.WriteLine($"Update document Type :{ result.GetPropertyValue<string>("GSM")}"); Console.ReadLine(); |
Cosmos DB’de Silme:
- “.Where(x => x.Children[0].FamilyName == “Durmaz”)” : İlk çocuğunun soyadı “Durmaz” olan document bulunur.
- “if(querydoc.Count()>0)” : Bu sorguya gore kayıt var mı diye bakılır.
- “client .DeleteDocumentAsync()”: Methodu ile seçilen document “doc.Id” alanına göre silinir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var querydoc = client.CreateDocumentQuery<Customer>( UriFactory.CreateDocumentCollectionUri("CustomerDB", "CustomerCollection")) .Where(x => x.Children[0].FamilyName == "Durmaz"); if(querydoc.Count()>0) { var doc = querydoc.AsEnumerable().First(); var result = client .DeleteDocumentAsync(UriFactory.CreateDocumentUri("CustomerDB", "CustomerCollection", doc.Id)) .Result.Resource; Console.WriteLine(result); } Console.ReadLine(); |
Bu makalede Azure CosmosDB nedir? Nasıl oluşturulur? Nasıl kayıt atılır, sorgulanır, güncellenir ve silinir gibi sorulara cevap bulmaya çalıştık. NoSql bir Db’de, sql sorgular çekerek işlem yapılabilen, 10 millisaniyede okuma, 15 millisaniyede yazma gibi hızlarda çalışılabilen ve azure üzerinde otomatik replica olan bir data center ile entegre olmak isteyen, herkese öneririm.
Geldik bir makalenin daha sonuna. Bir sonraki makalede görüşmek üzere hepinize hoşçakalın.
Source:
Son Yorumlar