31 Mart 2023 Cuma

Aggregations (Avg,Min,Max,Sum)

PUT ders/_bulk
  {"index":{"_id":1}}
  {"ders_adi":"MsSql","ders_suresi":"60","sinif":"A1","tipi":"Database","eğitmen":"Kaan","mevcut":"40"}
  {"index":{"_id":2}}
  {"ders_adi":"Css","ders_suresi":"45","sinif":"A2","tipi":"Frontend","eğitmen":"Kaan","mevcut":"12"}
  {"index":{"_id":3}}
  {"ders_adi":"Html","ders_suresi":"45","sinif":"A2","tipi":"Frontend","eğitmen":"alican","mevcut":"27"}
  {"index":{"_id":4}}
  {"ders_adi":"Java","ders_suresi":"25","sinif":"B1","tipi":"Backend","eğitmen":"karam","mevcut":"21"}
  {"index":{"_id":5}}
  {"ders_adi":"C sharp","ders_suresi":"50","sinif":"A2","tipi":"Backend","eğitmen":"ayşe","mevcut":"25"}
  {"index":{"_id":6}}
  {"ders_adi":"Oracle","ders_suresi":"50","sinif":"B2","tipi":"Database","eğitmen":"ayşe","mevcut":"32"}
    {"index":{"_id":6}}
  {"ders_adi":"Jquery","ders_suresi":"50","sinif":"B3","tipi":"Database","eğitmen":"ayşe","mevcut":null}

AVG
ilgili fieldin ortalamasını alır. İlgili fieldda null değerler varsa onları missing ile 0 değeri verebiliyoruz.
GET ders/_search
{
  "aggs": {
    "ortalama": {
      "avg": {
        "field": "mevcut",
        "missing": 0
      }
    }
  }
}

MİN
GET ders/_search
{
  "aggs": {
    "minimum": {
      "min": {
        "field": "mevcut"
      }
    }
  }
}

MAX

GET ders/_search
{
  "aggs": {
    "maximum": {
      "max": {
        "field": "mevcut"
      }
    }
  }
}

SUM
Kann öğretmeninin sınıf mevcudunun toplamını alacağız.
GET ders/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "eğitmen": "Kaan"
        }}
      ]
    }
  },
  "aggs": {
    "ortalama": {
      "sum": {
        "field": "mevcut"
      }
    }
  }
}
.

30 Mart 2023 Perşembe

Id, Wildcard ve Prefix ile sorgulama

PUT ders/_bulk
  {"index":{"_id":1}}
  {"ders_adi":"MsSql","ders_suresi":"60","sinif":"A1","tipi":"Database"}
  {"index":{"_id":2}}
  {"ders_adi":"Css","ders_suresi":"45","sinif":"A2","tipi":"Frontend"}
  {"index":{"_id":3}}
  {"ders_adi":"Html","ders_suresi":"45","sinif":"A2","tipi":"Frontend"}
  {"index":{"_id":4}}
  {"ders_adi":"Java","ders_suresi":"25","sinif":"B1","tipi":"Backend"}
  {"index":{"_id":5}}
  {"ders_adi":"C sharp","ders_suresi":"50","sinif":"A2","tipi":"Backend"}


Id ile Sorgulama
Idsi 2 ve 3 olan kayıtları getir.
GET ders/_search
{
  "query": {
    "ids": {
      "values": [2,3]
    }
  }
}



Wildcard ile sorgulama.
Sonu tipi alanında sonu end ile biten kayıtları getir.
GET ders/_search
{
  "query": {
    "wildcard": {
      "tipi": {
        "value": "*end"
      }
    }
  }
}


Prefix ile sorgulama
Prefix wildcarda oranla daha performanslı ve kaynakları daha az kullanan bir yapıdır.


Sorting ve Pagination

PUT ders/_bulk
  {"index":{"_id":1}}
  {"ders_adi":"MsSql","ders_suresi":"60","sinif":"A1","tipi":"Database"}
  {"index":{"_id":2}}
  {"ders_adi":"Css","ders_suresi":"45","sinif":"A2","tipi":"Frontend"}
  {"index":{"_id":3}}
  {"ders_adi":"Html","ders_suresi":"45","sinif":"A2","tipi":"Frontend"}
  {"index":{"_id":4}}
  {"ders_adi":"Java","ders_suresi":"25","sinif":"B1","tipi":"Backend"}
  {"index":{"_id":5}}
  {"ders_adi":"C sharp","ders_suresi":"50","sinif":"A2","tipi":"Backend"}


Pagination

Array gibi çalışır. 0 dan başla ilk iki kaydı getir.

GET ders/_search
{
  "size": 2,
  "from": 0
}


Sorting

GET ders/_search
{
  "sort": [
    {
      "ders_adi.keyword": {
        "order": "desc"
      }
    }
  ]
}

.. 

Uri ve Dsl query

PUT ders/_bulk
  {"index":{"_id":1}}
  {"ders_adi":"MsSql","ders_suresi":"60","sinif":"A1","tipi":"Database","eğitmen":"Kaan","mevcut":"40"}
  {"index":{"_id":2}}
  {"ders_adi":"Css","ders_suresi":"45","sinif":"A2","tipi":"Frontend","eğitmen":"Kaan","mevcut":"12"}
  {"index":{"_id":3}}
  {"ders_adi":"Html","ders_suresi":"45","sinif":"A2","tipi":"Frontend","eğitmen":"alican","mevcut":"27"}
  {"index":{"_id":4}}
  {"ders_adi":"Java","ders_suresi":"25","sinif":"B1","tipi":"Backend","eğitmen":"karam","mevcut":"21"}
  {"index":{"_id":5}}
  {"ders_adi":"C sharp","ders_suresi":"50","sinif":"A2","tipi":"Backend","eğitmen":"ayşe","mevcut":"25"}
  {"index":{"_id":6}}
  {"ders_adi":"Oracle","ders_suresi":"50","sinif":"B2","tipi":"Database","eğitmen":"ayşe","mevcut":"32"}
    {"index":{"_id":6}}
  {"ders_adi":"Jquery","ders_suresi":"50","sinif":"B3","tipi":"Database","eğitmen":"ayşe","mevcut":null}

Yukarıdaki gibi bulk insert ile elasticsearche kayıtlarımızı insert ettik.

Uri Query
GET ders/_search?q=ders_suresi:45

DSL Query
Match ile search ederken arama kriterini nasıl yazarsak yazalım match eder. örn. JAVA,JaVA
GET ders/_search
{
  "query": {
    "match": {
      "ders_adi": "Java"
    }
  }
}

Term ile serach ederken arama kriterini küçük harflerle yazmamız gerekir.örn java
GET ders/_search
{
  "query": {
    "term": {
      "ders_adi": "Java"
    }
  }
}


İndex içerisindeki sadece belli alanları getirmek istiyorsak 
GET ders/_search
{
"_source": ["ders_adi","eğitmen"]
}

Compand Query:

AND Query
GET ders/_search
{
  "query": {
    "bool": {"must": [
      {"match": {
        "sinif": "A2"
      }},
      {"match": {
        "tipi": "Frontend"
      }}
    ]}
  }
}

OR Query
GET ders/_search
{
  "query": {
    "bool": {"should": [
      {"match": {
        "sinif": "A2"
      }},
      {"match": {
        "tipi": "Frontend"
      }}
    ]}
  }
}

Must Not Query 

Sinifi A2 olan veya tipi frontend olan kayıtların hiç birisi gelmeyecek
GET ders/_search
{
  "query": {
    "bool": {"must_not": [
      {"match": {
        "sinif": "A2"
      }},
      {"match": {
        "tipi": "Frontend"
      }}
    ]}
  }
}

AMA Query
Sinif A2 olan ama Tipi frontend olmayan kayılar.
GET ders/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "sinif": "A2"
        }}
      ],
      "must_not": [
        {"match": {
          "tipi": "Frontend"
        }}
      ]
    }
  }
}

Filter Query
Ders süresi 10 ile 50 arasında olan kayıtlar
GET ders/_search
{
  "query": {
    "bool": {"must": [
      {"match_all": {}}
    ],
    "filter": [
      {"range": {
        "ders_suresi": {
          "gte": 10,
          "lte": 50
        }
      }}
    ]  
      
    }
  }
}


Ders tipi frontend olan, sinifi A2  olan ve ders süresi 10-50 arsında dersleri getir.
GET ders/_search
{
  "query": {
    "bool": {"must": [
      {"match": {
        "tipi":"Frontend"
      } },
      {
        "match": {
          "sinif": "A2"
        }
      }
    ],
    "filter": [
      {"range": {
        "ders_suresi": {
          "gte": 10,
          "lte": 50
        }
      }}
    ]
    }    
  }
}
.

Elasticsearch Optimistic Concurrency Control

Elasticsearch distributeddır. Bir document üzerinde  created,updated yada deleted operasyonları olursa documentin yeni versionu clusterdaki diğer replica nodelara gönderilir. Documentin eski bir versionun daha yeni bir versionu overwrite etmemesi için document üzeride gerçekleştirilen her işleme(CRUD), bu değişikliği koordine eden primary shard tarafından bir seq_no atanır. seq_no her operasyonda artar ve böylece daha yeni operasyonların eski operasyonlardan daha yüksek bir sıra numarasına sahip olması garanti edilir. Operasyonlar sırasında bu seq_no bilgisinide kullanarak eski versionların yeni versionları overwrite etmesi önlenmiş olur.

PUT products/_doc/1567
{
  "product" : "r2d2",
  "details" : "A resourceful astromech droid",
  "stock": 5
}

Yukarıdaki bir komut dizini product documenti oluşturacak ve ona primary_term ve seq_no atayacaktır.


Bir documenti get yaptığımızda bize belgenin en son seq_no ve primary_term değerleri gelir. Biz bu document üzerinde değişiklik yaptığımızda bu seq_no ve primary_term bizden önce değişikliğe uğramış mı onu kontrol ederiz. Bunuda if_seq_no ve if_primary_term paremetrelerini kullnarak yaparız. örneğin bizden önce birisi bu kayıt üzerinde işlem yaptıysa seq_no değişmiştir. Ozaman aşağıdaki işlem başarısız olur. Fakat kimse işlem yapmadıysa başarılı olur.

POST products/_update/1567?if_seq_no=0&if_primary_term=1
{
  "doc":{"stock": 4}
}

Yukarıdaki komutu stock bilgisinde değişiklik yaparak tekrar çalıştırırsak conflict hatası alırız. Çünkü artık seq_no değeri değişti.

POST products/_update/1567?if_seq_no=0&if_primary_term=1
{
  "doc":{"stock": 3}
}

29 Mart 2023 Çarşamba

Elasticsearch index,document ve mapping oluşturma

http://localhost:5601/app/dev_tools#/console


Create : ders isminde bir index ve buna ait bir document oluşturuyoruz.

PUT ders/_doc/1
{
  "ders_adi":"Css",
  "ders_suresi":60
}

.

Get: 1 nolu documetin bilgilerii getirir.

GET ders/_doc/1


Update:

POST ders/_update/1
{
  "doc":{"ders_suresi":45}  
}

Mapping: Schema oluşturmamız sağlar.

Elasticsearch schema-free bir yapıda iken neden her doküman bir type’a ait ve her type shcema gibi bir mapping içerir?

Elasticsearch schema-free’dir çünkü hiç bir şemaya sıkı sıkıya uymak durumunda değil ve tüm alanları içermek zorunda değildir.Üstüne üstlük documenetlar schemada olmayan bir alan da içerebilirler. Mapping ise o ana kadar indexlenmiş datalardaki en geniş property kapsamını tanımlar ve yeni bir alan geldiğinde elasticsearch otomatik olarak yeni alanı mappinge ekler. Bunu yaparken kendisi alanın tipini belirleyip daha doğrusu tahmin edip o şekilde ekler. Örneğin, değer 7 ise bunu long olarak varsayar. Ancak bu bazı durumlarda sıkıntı çıkarır.  Aslında alan string ise ve ilerleyen zamanda “hello world” eklemeye kalkarsanız fail olur. Bu sebeple productiondaki en safe yol mappingi indexlemeden önce belirlemek olacaktır.
PUT /ders
{
  "mappings": {
    "properties": {
        "ders_adi":{"type": "text"},
        "ders_suresi":{"type": "integer"},
        "eğitmen":{
          "properties": {
            "adi":{"type":"text"},
            "soyadi":{"type":"text"},
            "yasi":{"type":"integer"}           
          }
        }
    }
  }
}

oluşturduğumuz mappinge ulaşmak için 

GET ders/_mapping

mapping içerisindeki belli bir propertye ulaşmak için

GGET ders/_mapping/field/eğitmen.yasi

Delete İndex

DELETE /ders

Elk Docker Kurulum

docker-compose.yml isminde bir dosya oluşturup içerisine aşağıdaki komutları yapıştırıyoruz. 

"docker-compose up" ile çalıştırıyoruz

http://localhost:5601/app/dev_tools#/console

Yukarıdaki adresten kibana ya bağlanıyoruz.

version: '3.6'
services:
  Elasticsearch:
    image: elasticsearch:7.16.2
    container_name: elasticsearch
    restart: always
    volumes:
    - elastic_data:/usr/share/elasticsearch/data/
    environment:
      ES_JAVA_OPTS: "-Xmx256m -Xms256m"
      discovery.type: single-node    
    ports:
    - '9200:9200'
    - '9300:9300'
    networks:
      - elk

  Kibana:
    image: kibana:7.16.2
    container_name: kibana
    restart: always       
    ports:
    - '5601:5601'
    environment:
      - ELASTICSEARCH_URL=http://elasticsearch:9200  
    depends_on:
      - Elasticsearch  
    networks:
      - elk
volumes:
  elastic_data: {}

networks:
  elk:
..

Elastic Search

12 Mart 2023 Pazar

MongoDB

Schema Format

Github MongoDB Example

MongoDB'de Schema tasarımı ölçeklenebilir, hızlı ve uygun fiyatlı bir veritabanı oluşturmanın en kritik parçasıdır. Doğru schema tasarımı MongoDB yönetiminde en çok gözden kaçan durumlardan birisidir. Relational schema tasarımından sonra MongoDByi öğrenenler aynı relational schema tasarım gibi düşünerek schemaları tasarladığında MongoDB'nin sunduğu avantajlardan tam olarak yararlanamamaktadır. 

Schema Design Relational vs. MongoDB

MongoDB schema tasarlarken iç güdüsel olarak verilerimizi küçük tablolara bölmek isteriz. Bu gayet normal bir durumdur fakat schemaları bu şekilde tasarladığımızda MongDB'nin gerçek faydasını göremeyiz. Aşağıda farkları göreceğiz.

Relational Schema Design
Relational schema tasarlarken, developerlar genellikle schemaları querylerden bağımsız olarak modeller. Hangi dataların olduğunu belirleriz ve veri tekrarını önlemek için 3rd normal form ile verileri tablolara ayırırız.(Referencing)


Yukarıdaki örnekte User dataları ayrı Professions ve Cars olarak iki ayrı tabloya ayrılmıştır ve user_id foreingkey ile birbirine bağlanmıştır. Bu foreingkey kullanılarak veriler joinleyebiliriz.

MongoDB Schema Design
MongoDB schema tasarımı,relational schema tasarımından çok farklı çalışmaktadır.
  • Birlikte Erişilmesi Gereken Dataları Birlikte Depola. Tek bir MongoDB documentin boyutu 16 MB'ı aşamaz. Dizi alanlarını kullanarak birden çok documenti embedded etmek mümkün ve yaygın olsa da, nesnelerin listesi kontrolsüz bir şekilde büyürse document bu boyut sınırına hızla ulaşabilir. Ek olarak, embedded arraylerde büyük miktarda veri depolamanın sorgu performansı üzerinde büyük etkisi vardır.
  • Relational verilere seyrek erişim, genellikle documentleri embedded etmemeniz gerektiğine dair başka bir ipucudur.
  • Relational kurulurken eğer ki relation olan datanın boundarysi belliyse embedded uygulanabilir. Örneğin bir kişinin en fazla 2 yada 3 emaili olabilir. Bu gibi miktarı belli olan dataları embedded tutabiliriz. Fakat boyutu sürekli olarak artabilecek dataları ayrı bir schemada tutmalıyız.
MongoDB de schema desing ederken önemli olan tek şey applicationımız için iyi çalışan bir schema tasarlamaktır. Bu veritabanına yapacağımız queryleri düşünmek her zaman önceliğimiz olmalıdır. Sorgu ihtiyacına göre veritabanını tasarlamalıyız.
  • Store the data
  • Provide good query performance

Verilerimizi ayrı collections yada documentslere bölmek yerine, MongoDBnin document based tasarımından yaralanarak User objesinin içerisinde array ve obje olarak tanımlıyoruz.(Embedding) Artık tek bir query ile usera ait tüm datalara ulaşabiliyoruz.


Embedding vs. Referencing
MongoDB ile dataları embeded olarak yada reference kullanarak $lookup operatorü yardımıyla join edecek şekilde kurgulayabiliriz.

Embedding
denormalized data schema olarak bilinir.
Advantages:
  • İhtiyacımız olan tüm dataları tek bir query ile elde edebiliriz.
  • Kodumuz içerisinde join yada $lookup kullanmaya ihtiyacımız kalmaz.
  • Data read ve update için single database operation yeterlidir.
Limitations:
  • Dublicate dataya neden olur.
  • Large documentler daha fazla yük anlamına gelir.
  • MongoDB'de 16 MB document boyutu sınırı vardır. Tek bir documente çok fazla veri embeded ediyorsanız , potansiyel olarak bu sınıra ulaşabilirsiniz. 
Ne zaman kullanabiliriz?
  • Entityler arasında "contains" yada "has-a" relationship varsa kullanabiliriz.
  • Entityler arasında one-to-one, one-to-few  yada one-to-many ilişkisi varsa kullanabiliriz.

Referencing
Schema tasarlarken diğer bir seçenekte Unique Object Id kullanarak documentlerin bir birine $lookup operatörüyle bağlamaktır.. Referencing sql querydeki join operatörüne benzer şekilde çalışır. Daha verimli ve ölçeklenebilir queryler yapmak için verileri bölmemize ve aynı zamanda veriler arasındaki ilişkileri sürdürmemize olanak tanır. Normalized data schema olarakta bilinir.
Advantages:
  • Dataları split ettiğimiz için daha küçük documenlere sahip olacağız.
  • İhtiyacımız olmayan dataları query ile çekmemiş olacağız.
  • Dublicate olan veri miktarı azalmış olur. Fakat burada dublicate olduğu halde daha iyi bir schemaya sahip olacaksak verinin dublicate olduğu schemayı seçmeliyiz.(embedding)
Limitations:
  • Referenced documentte, ihtiyacmız olan dataları elde etmek için  minimum iki query ve $lookup kullanmamız gerekebilir.
Nezaman kullanabiliriz ?
  • many-to-many relationshiplerde kullanabiliriz.


Storing Together What Needs to be Accessed Together
Tipik bir relational databasede, veriler tablolarda tutulur. Örneğin üniversitedeki öğrencileri temsil eden bir tabloda, her öğrencinin adını, soyadını, doğum tarihini ve UniqId bilgisini tutarız. Her tablo single subjecti temsil eder. Bir öğrencinin mevcut çalışmalarını, burslarını veya önceki eğitim hayatıyla ilgili bilgileri depolamak istiyorsak, bu bilgileri ayrı bir tabloda tutmak mantıklı olabilir. Daha sonra bu tabloları bir birine foreingkey ile bağlayarak anlamlı bir connection sağlayabiliriz.

Örneğin, her öğrencinin burs durumunu açıklayan bir tablo, öğrencilere ait tc numarayı refere edebilir. Bu burs tablosuna öğrencinin adını veya adresini yada daha farklı bilgilerini  eklememize gerek kalmaz. Böylece veri tekrarını önlemiş oluruz. Öğrenciye ait tüm bilgileri almak istediğimizde bu foreingkeyler kullanılarak joinleme işlemi yapılır ve data elde edilir. Referanslar aracılığıyla ilişkileri tanımlamanın bu yöntemi, normalized data model olarak bilinir. Verileri bu şekilde depolamak - birbiriyle ilişkili birden çok ayrı, özlü nesne kullanmak - document-oriented veritabanlarında da mümkündür. Document-oriented veritabanları yukarıdaki yapılara ek olarak bu dataları embeded olarak da tanımlayabilme imkanı ve özgürlüğü vermektedir.

Document-oriented veritabanlarının altında yatan kavram "birlikte erişilecek olanı birlikte depolamaktır.". Üniversitenin, her öğrencinin iletişim bilgileriyle birlikte birden fazla e-posta adresini kaydetmek istediğini düşünelim.


Yukarıdaki örnekte document bir embedded email adress listesi içermektedir.
Tek bir documentte birden fazla konuyu temsil etmek, denormalize edilmiş bir veri modelini karakterize eder. Uygulamaların, birden fazla ayrı nesneye ve koleksiyona erişmeye gerek kalmadan, belirli bir nesne (burada bir öğrenci) için ilgili tüm verileri tek seferde almasına ve değiştirmesine olanak tanır. Bunu yapmak, bütünlüğü garanti etmek için çoklu belge işlemlerini kullanmak zorunda kalmadan böyle bir belge üzerindeki işlemlerin atomikliğini de garanti eder.

Embedded document kullanılarak birlikte erişilmesi gerekenleri bir arada depolamak, genellikle verileri document-based bir veritabanında temsil etmenin en uygun yoludur.

One-to-One
Bir nesnenin, başka bir türden nesneyle arasındaki bağlantıyı ifade eder. Yani iki farklı nesne arsındaki ilişkidir.
one-to-one verileri key-value pairs olarak modelleyebiliriz.

Her öğrencinin bir adet kimlik kartı vardır. Bir kart asla birden fazla öğrenciye ait olamaz ve hiç bir öğrencinin birden fazla kimlik kartı olamaz.Kimlik kartı öğrenci olmadan anlamsızdır.


Bu örnek belgenin id_card alanında, tek bir değer yerine, öğrencinin kimlik numarası, kartın veriliş tarihi ve kartın son kullanma tarihi ile açıklanan kimlik kartını temsil eden embedded document bulunduğuna dikkat edin. Kimlik kartı, gerçek hayatta ayrı bir nesne olsa da esasen öğrenci Sammy'yi tanımlayan belgenin bir parçası haline gelir. Genellikle, belge şemasını bu şekilde yapılandırmak, böylece ilgili tüm bilgileri tek bir sorgu aracılığıyla alabilirsiniz.


One-to-Few
Bir öğrencinin bir kaç adresi olabilir, bir arabanın çok sayıda parçası olabilir veya bir alışveriş siparişi bir kaç  öğeden oluşabilir. Bu örneklerin her biri bire çok ilişkiyi temsil eder.
Örneğin belirli bir öğrenciyle ilişkili bir kaç e-posta adresi saklamamız gerekebilir. Uygulamamız için bir kullanıcının birkaç farklı e-posta adresinden  daha fazlasına sahip olması olası değildir. Bunun gibi ilişkileri one-to-few olarak tanımlayabiliriz.

one-to-one ilişkilerde embedded olarak tanımlayabiliyorken one-to-many ilişkileri modellemenin birkaç yolu vardır.

Cardinality:Belirli bir kümedeki bireysel öğelerin sayısıdır. Bir sınıfta 30 öğrenci varsa o sınıfın Cardinality ölçüsü 30 dur. one-to-many ilişkilerde "çok"un boyutu, verileri nasıl modelleyeceğinizi etkiler. Bu boundedın sınırları belli mi ? soracağımız soru bu olmalıdır.

Independent access: Bazı related verilere ana nesneden ayrı olarak nadiren erişilir. Örneğin bir öğrencinin e-posta adresine diğer bilgiler olmadan erişmek alışılmadık bir durumdur. Öte yandan, bir üniversitenin derslerine, bu derse kaydolan öğrencilerden bağımsız olarak erişilmesi ve güncellenmesi gerekebilir. Related bir documente tek başına erişip erişmeyeceğimiz, verileri nasıl modelleyeceğimizi etkiler.

Bu yapıyı kullanarak, bir öğrencinin documentini her aldığınızda, aynı okuma işleminde embeded e-posta adreslerini de alırsınız.


One-to-Many With Child Reference

Öğrenciler ve e-posta adresleri arasındaki ilişkinin doğası, bu ilişkinin bir document-based veritabanında en iyi şekilde nasıl modellenebileceği konusunda bilgi verdi. Öğrenciler ve katıldıkları dersler arasındaki ilişki arasında bazı farklılıklar vardır, dolayısıyla öğrenciler ve dersleri arasındaki ilişkileri modelleme şekliniz de farklı olacaktır.


Yukarıdaki gibi Öğrenci documenti içerisine coursesları embedded olarak eklediğimizi düşünelim. 
Cardinality olarak ele aldığımızda bir öğrenci bir den fazla course katılabilir ve yıllar içinde daha bir çok course  kayıt olabilir. Ve böyle çok sayıda kayıt eklenirse öğrenci documenti çok büyür ve hantallaşmaya başlayabilir.
Independent access olarak ele aldığımızda coursların listesini öğrencilerden bağımsız olarak kendi başlarına query etme ihtiyacımız olabilir.  Örneğin bir pazarlama broşürü oluşturmak istiyoruz ve bu broşüre course isimlerini yazdırmak istiyoruz. Bunlara ek olarak coursların zaman içerisinde güncellenmesi gerekecektir. Dersi veren profesör değişebilir, ders programı değişebilir veya ön koşullarının güncellenmesi gerekebilir.

Coursları, öğrenci içerisine embedded olarak ekleseydik, tüm coursların listesine ulaşmak zahmetli olurdu. Ayrıca bir coursenin güncellenmesi gerektiğinde tüm öğrenci kayıtlarını gözden geçirmemiz ve kurs bilgilerini her yerde güncellemeniz gerekir. Bunların hepsi courseyi ve öğrenciyi ayrı olarak modellememiz için geçerli bir nedendir.(don't embed).

Courses


Course bilgilerini bu şekilde depolamaya karar verirseniz, hangi öğrencilerin hangi kurslara katıldığını öğrenebilmeniz için öğrencilerle bu kurslar arasında bağlantı kurmanın bir yolunu bulmanız gerekir. İlgili nesnelerin sayısının çok fazla olmadığı bu gibi durumlarda, özellikle one-to-many ilişkiler söz konusu olduğunda, bunu yapmanın yaygın yollarından biri child referansları kullanmaktır.



Mümkün olduğu kadar joins/lookups dan kaçınmalıyız. Ancak yukarıdaki gibi Öğrenci ve Courslara ayrı ayrı erişmemiz gerekiyorsa tüm bu yapıları embedded etmek yerine  ayrı ayrı schemalara koymalıyız.

One-to-Many With Parent Reference

Child referansları kullanmak, doğrudan parent documentin içine gömmek için çok fazla related nesne olduğunda işe yarar, ancak miktar hala bilinen sınırlar içindedir. Ancak, related documentlerin sayısının sınırsız olabileceği ve zamanla artmaya devam edeceği durumlar vardır.

 Örneğin,Öğrencilerin bir çok mecraya mesaj gönderebileceği bir mesaj panosu olduğunu düşünelim. Bu mesaj bir subject ve bir bodyden oluşsun.


Öğrencinin gönderdiği tüm mesajları Öğrenci documenti içerisinde embedded olarak tuttuğumuzu düşünelim.

Yukarıdaki şekilde embedded olarak tanımlarsak, Eğer öğrenci sürekli mesaj gönderirse öğrenci documentinin 16mb sınırını aşma ihtimali olacaktır. Aynı zamanda mesaj sayfası panosu üzerinden öğrenciler tarafından en son gönderilen mesajlar gösterilmesi gerekirse mesajların öğrenciler olmadan erişilebilir olması gerekebilir. Ayrıca öğrenci documentine her eriştiğimiz de bu mesajların yüklenmesi gerekmiyorsa bu mesajların öğrenci documentten ayrı modellenmesi daha yerinde bir karar olacaktır.

Bir başka çözüm olarakta child referenceleri kullanalım ve burada öğrenci documenti içerisinde mesajlara ait objectIdyi refere olarak bir collectionda tutalım.


Bu örnekte, message_board_messages alanı artık Sammy tarafından yazılan tüm iletilere yapılan child referenceleri depolar.Buna ek olarak artık mesajlara öğrenciden  bağımsız olarak erişmek mümkün olacaktır. Ancak, child reference yaklaşımı kullanılarak öğrencinin document boyutu yavaş yavaşta olsa büyüyecektir.Öğrenci 4 yıl boyun binlerce mesaj yazarsa bu öğrenci documenti 16MB  sınırını aşabilir. Bunlara ek olarakda boyut büyüdükçe Öğrenci sınıfı hanstallaşacaktır ve performans sorunu doğacaktır.

Bu tür durumlarda child referencenin tam tersi olarak mesaj documenti üzerinde öğrenciye ait reference bulanacak ve böylece parent reference olacaktır.

Parent referansları kullanmak için, mesajı yazan öğrenciye bir referans içerecek şekilde mesaj document şemasını değiştirmeniz gerekir:


Yeni posted_by fieldı öğrencinin documentinin nesne tanımlayıcısını içerdiğine dikkat edin. Artık öğrenci documenti, gönderdikleri mesajlarla ilgili herhangi bir bilgi içermeyecek:


Bir öğrenci tarafından yazılan mesajların listesini almak için, mesaj koleksiyonunda bir query atar ve post_by fieldına göre filtreleme yaparsınız. Mesaj ve Öğrenciyi ayrı schemalara koyarak öğrencinin gönderdiği mesaj listesinin büyümesi öğrenci doumentini hiç bir şekilde etkilemeyecektir.

Not: Documentlere bağımsız olarak erişilmesi gerekip gerekmediğine bakılmaksızın, ilgili documentin miktarının sınırsız olduğu one-to-many ilişkiyi modellerken , genellikle ilgili documentleri ayrı ayrı saklamanız ve bunları parent documente  bağlamak için parent referansları kullanmanız önerilir.

Many-to-Many
Bir to-do uygulaması olduğu düşünelim. Bir userın many task alabileceğini ve bir taskın many usera atanabileceğini düşünelim. 


Her User task isminde bir sub-arraye sahiptir. Aynı şekilde her Taskta owners isminde bir sub-arraye sahiptir.

Many-to-many Embedded Example
Product ve Customer arasında many-to-many ilişkisi olduğu düşünelim. Bunlar arasında Orders isminde bir tablo tutulur ve bu tablo Customer içerisinde embedded olarak eklenir. Bu şekilde yapılan bir tasarımda productın fiyatı güncellense bile biz hala sipariş verdiğimiz zamanki priceyi kaydetmiş oluyoruz. Bunun bize avantajı bu oluyor.



Use Indexes For Frequent Operations

MongoDB de verileri daha küçük parçalara bölmek(tablo) yerine birlikte erişilen parçları embedded tasarladığımız için bu documentlerin boyutunun oldukça büyük olmasıda normaldir. Bu durum doğal olarak performansı etkileyecektir, ancak indexlerle bunu çözebiliriz. MongoDB'deki indexler, relational veritabanlarıyla hemen hemen aynı şekilde çalışır. Bu özel veri structlar , sık kullanılan queryler için veri eşleşmesini(matching) hızlandırmak amacıyla tüm documentin küçük bir subsetini depolar.

Örneğin User datalarıyla order historysini tek bir document içerisinde embedded olarak tuttuğumuzu ve geçen ay X ürününü sipariş etmiş kullanıcıları bulmak istediğimizi düşünelim. Normalde (indeksler olmadan) MongoDB'nin tüm User collectionları  taraması, User documentlerden birer birer geçmesi ve her User için son sipariş verilerini kontrol etmesi gerekir. Bu korkunç değil; veritabanı bu şekilde birçok işlemi gerçekleştirir. Ancak veritabanından bu tür bir eşleştirmeyi sık sık sorarsanız, indeksleme size çok yardımcı olacaktır. Örneğimize geri dönersek - indexlerle MongoDB, verilere işaretçiler içeren(pointer to data ) ayrı, küçük bir liste depolar.(örneğin, kullanıcı kimliği, e-posta adresi veya son sipariş tarihi).


8 Mart 2023 Çarşamba

ELK

 Githup ELK example

  • Elasticsearch bir search ve analitic enginedir.
  • Kullanımı ve ölçeklendirmesi kolaydır.
Use Cases
  • Search işlemi gerektiren uygulamalarda sıklıkla kullanılır. 
  • Auto-complition web sitelerinde gördüğümüz otomatik tamamlamada kullanılır.
  • Sistem loglarını, metriclerini depolayıp analiz etmede kullanılır.
  • Elasticsearch ve Kibananın birlikte bize sunduğu Machine learning modelleriyle veriyi gerçek zamanlı analiz etmede kullanılır.
  • Büyük ölçekli datalarda analiz işlemlerinde başarılıdır. Gerçekten terabytlarca datayı çok kolay bir şekilde indexleyip sorgulama performasnı yüksek şekilde hizmet veri
Elastic search faydaları 
  • Büyük bir veri yığını içerisinde hızlı search edebilme.
  • Yazım yanlışı: biiskilet kelimesini arattığımızı düşünürsek bisiklet olduğunu anlayıp eşleştirebilir.
  • Eş anlamlılar: Arattığımız cümlede "taşıt" kelimesi geçiyorsa "vasıta" kelimesi geçen sonuçları da bize getirebilir.
  • Türetme ve Öneri:Kullanıcı search için kelime girerken daha o sırada onun populer searchleri görebilmesini sağlayabiliriz, suggestionlarla en çok arananlar popular sonuçlar ya da eşanlamlıları da search edebiliriz.
  • İstatistik: Elimizdeki search verilerinden istatistiksel datalar da çıkarabiliriz.

Elasticserachü direkt olarak bir NoSQL veritabanı olarak görmek yanlıştır. Elasticsearchün geliştirilme amacı bir search ve analitic engine olarak kullanmaktır. Yani elasticsearchü docüment based bir veritabanı olarak kullanmamalıyız. Böyle bir ihtiyacımız var ise MongoDBye yönelmeliyiz.

Elastic Stack
Elasticsearch tarafından geliştirilen logstash, kibana, x-pack, beats gibi ürünleride kapsayan yapıya verilen isimdir. Bu ürünler genelde birlikte kullanılır.

Kibana: Elasticsearchün yönetimsel işlevlerini gerçekleştirebildiğimiz veri görselleştirme ile alakalı özellikleri kullanabildiğimiz ve cluster yönetimiyle alakalı işlerde kullandığımız yönetimsel web arayüzüdür.

Logstash: Uygulama loglarının elasticserache gönderilmesini sağlar. input,printer ve output olmak üzere üç tane ana yapısı vardır. Kaynaktaki veriyi input aşamasında alıp veriyi filtreden geçirir ve output alanında verdiğimiz hedefe datanın gönderilmesinden sorumludur.

X-pack: Elastic ve Kibanaya extra özellik kazandıran extension gibi düşünülebilir. Security, LDAP entegrasyonu, User Role tanımları, Elastic monitoring, Alerting gibi birçok özelliği x-pack aracılığıyla kullanıyoruz. 

Beats: Datanın toplanmasını sağlar.Collect data. Filebeat en yaygın olarak kullanılanıdır. Genelde logstash ile çalışırlar. Toplanan data logstash aracılığıyla elasticsearche gönderilir.

Elastic’in FileBeat adlı ürünü, container loglarını yakalayabilme kapasitesine sahip bir ürün. Ayrıca yakaladığı logları diğer Elastic ürünlerine de direkt olarak iletebiliyor (Logstash’ iletmek ya da direkt olarak Elasticsearch’e yazmak gibi). Kibana ile de bu logları görselleştirebiliyorsanız, container olarak koşan her uygulama için ayrı bir log yapısı kurmaya gerek kalmadan bütün bu operasyonu tek bir merkezden yönetebilirsiniz.
Arthitecture

Node: Elasticsearch instance'larına verilen isimdir. Her node datanın bir parçasını depolar. Bu sayede distributed ve scaleable bir ortam sunar. Node kavramı direkt olarak server kavramına denk gelmez. Çünkü bir adet server üzerinde birden çok elacticsearch instancesi farklı portlarda çalışabilir. Fakat bu production ortamlarında önerilen bir yöntem değildir. Her nodun farklı bir serverlarda çalıştırılması önerilmektedir.

Cluster: Bir veya daha çok elasticsearch node'unun iletişim halinde çalışmasıyla ortaya çıkan yapıdır. Her node bir clustera aittir. Single node çalışan bir elasticsearchte bile bir Cluster kavramı vardır. Bir node başlatıldığında otomatik olarak configurasyonda tanımlanmış clustera dahil olur.

Document: Elasticsearchte datalar documentler halinde tutulur.Documentler RDBMS'te row alanına denk gelmektedir. Documentlerde içerisinde field denilen ve datayı tanımlayan alanları barındırır. Fieldlarda RDMBSteki kolonlara denk gelmektedir.

Index: Datalar elastic searchte document olarak depolanır. Her bir document bir index içerisinde depolanır. İndexlerde benzer yapıda olan document objelerinin oluşturduğu gruptur. İndexler bir veya daha fazla sharddan meydana gelen logical yapılardır. Birden çok node üzerine dağıtılırlar. 

Shard: 
Shardingin ne olduğuna girmeden önce, neden shardinge ihtiyacımız olduğu üzerine biraz konuşalım. Çok fazla dökümana sahip olan bir indexiniz olduğunu ve totalde 1 terabyte boyutu olduğunu düşünelim. Ancak elinizde iki adet makinanız yani nodeunuz var. Her biri de 512 GB bilgi store edebiliyor. Açıkça hiç bir nodeunuz dökümanı komple taşıyacak kadar kapsamlı değil. Bu durumda dataları bölmemiz gerekecektir. Ve burada sharding konsepti imdadımıza yetişir. Sharding indexleri adı shard olan daha küçük parçalara böler. Bir veri bütününün yatayda bölümlenmiş halidir. Yani her shard indexin bir subsetini taşır ve kendi içinde bağımsızdır. Yani shardı bağımsız index olarak düşünebiliriz.

Sharlar büyük ölçekli dataların dağıtık mimaride depolanmasını sağlayan yapılardır. İndex datası shard adı verilen daha küçük parçalara bölünerek depolanır. Bir indexsin shardları clusterda birden çok node üzerinde dağıtılır.  Primary ve replica olmak üzere iki tip shard vardır. Bir indexte yer alan her document bir primary sharda ait olmak zorundadır. Replica shardlar ise primary shardların kopyasıdır. Replica shardlar sayesinde diğer veritabanlarında olduğu gibi datanın bir kesinti yada  hata durumda kaybolmamasını sağlar. Bunun dışında replica shadrlar üzerinde readonly işlemler yapılarak okuma işlemi yapılır ve performans arttırılır. Replicalar esasen bir kaç ana amaca hizmet eder. İlki high avalibilityi sağlayabilmektir. Yani node ya da shard fail olduğunda bu shardın eksikliğini replikasyon ile tamamlayabiliriz. Diğer bir amaç ise search performansını artırmaktır. Çünkü searchler replika serverlarda da paralelde çalıştırılabilir. Yani aslında replikalarda cluster’in search gücünün bir parçasıdır. Bir diğeri de load balancingi sağlayabilmesidir.

Dökümanları Shardlara Dağıtmak – Routing mekanizması
Peki elastik search bu shard yapısını nasıl yönetir. Dökümanın hangi shardda olacağını, dökümanların shardlara eşit olarak dağıtılmasını vs random yapmayacağı aşikar. Döküman boyutları eşit olmalı. Bu sürece routing denir ve routing süreci defaultta otomatik işler. Çoğu kullanıcı da bunu manuel yönetmek istemez.

Bu değer daha sonra bir hash fonksiyonuna bölme için kullanılmak üzere  sayı üretmesi için geçer. Bu sayının kalanı shard sayısını veririr. Bu elastic searchin specific dokumanlarının yerini nasıl belirlediğidir. Search query çalıştırıldığında, süreç farklıdır. Query tüm shardlara paylaştırılır.

 Shard sayısını değiştirirsek, routing formülünü çalıştırmanın sonucu dökümanlar için değişir. Beş shard varken bir belgenin Shard A’da depolandığı bir örneği düşünün, çünkü o sırada routing formülünün sonucu buydu. Shard sayısını değiştirebildiğimizi ve onu yedi olarak değiştirdiğimizi varsayalım. Dökümanı id’ye göre aramaya çalışırsak, routing formülünün sonucu farklı olabilir. Şimdi, document aslında Shard A’da saklansa bile formül Shard B’ye yönlendirilebilir. Bu, document hiçbir zaman bulunamayacağı ve gerçekten bazı baş ağrılarına neden olacağı anlamına gelir. Bu nedenle, bir index oluşturulduktan sonra shard sayısı değiştirilemez, bu nedenle yeni bir index oluşturmanız ve dökümanları ona taşımanız gerekir

Type: Benzer documentleri tanımlar. 

Mapping: Indexlenecek doumentte yer alan fieldların yapısını belirler. Mapping işlemi otomatik yapılabilceği gibi manuelde yapılabilir. 



Çalışma Prensibi

Aşağıdaki görselde  node-1, node-2 ve node-3 nodelarının birleşimiyle  Elastic_Prod_Cluster1 clusteri oluşturulmuştur.Toplamda index A, index B ve index C olmak üzere üç adet indeximiz bulunmaktadır. Her bir indexte üç adet sharda bölünmüştür. Her shardında bir adet replicası bulunmaktadır. index A için incelersek  P1, P3 ve P3 index A için oluşturulmuş shardlardır. R1, R2 ve R3 te bu shardların replicalarıdır. 

Bir shardın primarysi ve replicası aynı node üzerinde olamaz. Yani  P1 ve bunun shardı olan R1 aynı node üzerinde olmaz. Görsele bakarsak P1 node-1 üzerindeyken R1 node-3 üzerindedir.Diyelimki node-1 de bir arıza çıktı. Böyle bir durumda node-3 üzerinde bulunan R1 replica shardı artık primary olacak ve artık read dışında write işlemide yapılabilecek. Aksi durumda  eğer P1 ve R1  node-1 üzerinde olsaydı  ve herhangi bir nedenle node-1e erişim sağlanamasaydı shard ve replica aynı anda kaybolmuş olcaktı. index A p1,p2 ve p3 shardlarından oluştuğu için index A nın p1 shardında bulunan dataları kaybetmiş olacaktık.



1 shardımız var ve 5 ayrı replikasını oluşturduk. Bu 5 ayrı replika nasıl orjinal sharda paralel update olacak? Yani aslında sistem nasıl çalışıyor?

Elastic search primary backup adında bir modeli data replikasyonu için kullanır. Yani replika grubunun primary shardı index operasyonları için entry point görevi görür. Yani biraz daha türkçeleştirirsek insert update delete gibi tüm operasyonlar primary sharda gider. Primary shard operasyonların validationu ve herşeyin doğru olduğunundan emin olmakla sorumludur. Bu görev, object beklenen bir alana number yollamaya çalışmak gibi her requestin yapısal olarak doğruluğunu denetleme gibi işleri de içerir. Operasyon primary shard tarafından kabul edildiğinde yine primary shard tarafından çalıştırılır. Operasyon tamamlandığında, aynı operasyon her replikaya yollanır. Eğer birden fazla replika varsa bu replikalar üzerinde paralel çalıştırılır. Yani güncel verinin snapshotı yerine operasyon elden ele taşınır. Bu operasyon tüm replikalarda doğru bir şekilde çalıştığında ve replikalar primary sharda response döndüğünde, primary shard da clienta operasyonun tamamlandığına dair response döner.




Elasticsearchün Sorgulamadaki Hızı 
Elasticsearch veriyi indexlerken inverted index denilen bir indexleme mekanizması kullanır. Bu sayede çok hızlı bir şekilde text search işlemleri gerçekleştirilir.


Yukarıdaki görseli incelersek inverted indexler document içerisinde yer alan terimlerin hangi documentle ilişkisi olduğunu tutan yapılardır.  örneğin yukarıdaki gibi she likes winter ve Wheather is too cold in winter olmak üzere iki adet documentimiz olsun. Bu documentler çeşitli filtrelerden geçirilerek termlere ayrılacaktır. Daha sonra termler hangi dökümanda hangi sırada ise ona göre inverted indexe kaydedilecektir. Termler tabloya sıralı bir şekilde kaydedilmektedir. Büyük küçük harf duyarlı olduğu için yukarıdaki tabloda ona göre sıralanmıştır. 

örneğin 
She termü 1. documentin 1. sırasındadır. Doc_Id 1 ve inverted Index 1,1

winter termü hem 1. documentte hemde 2. documentte yer almaktadır. Doc_ID 1,2 ve inverted indexi 
{1,3} Yani 1. documenti 3. kelimesi winterdır. {2,6) Yani 2.documentin 6. kelimesi winterdır.

Elastic Search Scaling

Elasticsearchin en önemli ve güzel özelliklerinden biri de scale out bir çözüm olmasıdır. Günden güne çok büyük verilerle uğraştığımız için scaling önemli bir faktör çünkü kimse o milyonlar boyutunda verileri tek bir makinada yani tek bir elasticsearch nodeunda karşılamak istemez.

Elasticsearch Clustera Node Ekleme
  • Clustera node eklemek search ve indexing performansını artırır çünkü queryler paralelde hem shardlar hem de replika shardlar tarafından çalıştırılabilir. (Performance) ;
    Bu kısmı biraz daha açarsak elinizde 900.000 documentlik bir elasticsearch nodeu olduğunu varsayalım. Bu tek node üzerinde bir request gönderdiğiniz zaman 900.000 adet döküman search edilecektir. Ancak eğer 3 node’unuz varsa 900.000 document bu nodelara 300k 300k 300k olarak dağılacaktır. Attığınız search requesti de paralelde 300k lık bir bütün içerisinde search yapacaktır.
  • Bir query üzerinden out of memory sorunu yaşıyorsa bu da node eklenerek önlenebilir.
    Bu şekilde datayı scale etmek bir bütün olarak cluster’a daha fazla memory eklemek anlamına da gelir yani çok fazla vakit alan veya out of memory memory veren intensive searchler ve aggregationlar için çözüm daha fazla node eklemek olabilir.
  • Replication konsepti ile herhangi bir sebepten bir node’ın çökmesinin veri kaybına yol açması önlenir. (Avalibilty, Fault tolerance system)
    Normal şartlarda elastic search clusterimiza eklediğimiz her yeni node için elasticsearch otomatik olarak shardları eşit dengeleme eğilimine girer. Eğer ki replika ayarlarınız da yapılıysa ki default olarak yapılı gelir, elasticsearch otomatik olarak replikaları da dağıtır. Böylece herhangi bir sebepten sizin primary shardınızın bulunduğu node’unuz çökerse, client tarafında hiç bir sıkıntı yaşanmadan replica shard üzerinden veriye erişim sağlayabilirsiniz.
Node Discovery
Clusterımıza yeni bir node daha ekledik. Peki ama eski node ile yeni node nasıl tanışacak yani birbirlerini nasıl bulacaklar . Aslında sadece Elasticesearch’ün değil tüm dağıtık sistemlerin bir konusu olan, clustera bir node katıldığında bu node’un nasıl discover olacağı ve eski nodelarla iletişim kuracağıdır. Elasticsearch’ün bunun için multicast ve unicast olarak adlandırılan iki farklı yöntemi vardır. İki yöntemi beraber de kullanabildiği gibi, default olarak multicast yöntemini kullanır.
  • multicast : Multicast networkteki diğer tüm nodelara, “benimle aynı clusterda olan var mı?” diye ping gönderip, response almasına dayanır. Aynı networkde çalışan çok sık IP eklenip çıkarılan esnek sistemlerde kullanışlı bir yöntemdir.
  • unicast: Unicast discovery elasticsearche bağlanmak ve cluster hakkında daha fazla bilgi sahibi olabilmek için host list’i kullanır. Bu IP adreslerinin çok sık değişmeyeceği production ortamları için idealdir. Örneğin elasticsearch.yml içerisinde discovery.zen.ping.unicast.hosts : [“10.0.0.3”, “10.0.0.4:9300”,”10.0.0.5[9300-9400]] gibi bir listemiz olabilir.

Master Node Election 

Elasticsearchümüz ayakta, nodelar birbirini buldu tanıştı. Şimdi sırada ne var? Master nodeun seçimi  Elasticsearch clusterında nodelar birbiriyle iletişim kurduğunda ikinci aşama olarak kimin master node olacağı konusunda uzlaşırlar. Peki master node neden var? nedir? ne iş yapar?. Master node ise cluster’in statetinden, shardlarının stateinden, indexten yani  genel anlamda slave nodelardan sorumlu olan nodedur. Eğer clusterınız tek nodedan oluşuyorsa bu node kendi kendini master node olarak seçer.

Master node belirlendikten sonra, ilk icraatı olarak tüm clustera ping atarak clusterin durumunu alive olup olmadığını belirlemeye calismaktır :). Bu duruma da fault detetion denir. Peki bir diğer klasik soru, madem master node diğer nodelar üzerinde yönetici rolune sahip, master node down olursa ne olur. Aslında elastic search’e göre tüm nodelar eğer ki settinglerindeki node.master’ı false’a set etmezseniz master eligible yani master çöktüğünde yerine geçebilecek  node’tur.

Clusterdan Node Silme

Clusterımızı oluşturduk. Nodelarımızı ekledik. Bu nodelar birbirini tanıdı. Masterlarını seçti vs vs. Peki ya clusterdan bir node inerse yahut sen bir nodeı kapatırsan ne olur?. İnen shardın replikaları otomatik olarak primary sharda döner. Bu elastic searchin yapacağı ilk şeydir. Çünkü indexin ilk olarak primary shardlara gider. Yani elasticsearch herhangi bir replicayı seçerek bunu primary sharda çevirebilir. Daha sonra elasticsearch kalan nodelar arasında replikalarını oluşturup dağıtır


Elastic Search Kullanım Örneği

Mysql ile birlik elastic searchün full text search özelliği kullanılacaktır.


Bir kayıt yukarıdaki gibi save edilip veritabanına kaydediliyorken aynı zamanda elastic searchede kaydedilmesini sağlayacağız. 
Paginationı, filter ve search özellikleriyle beraber tüm fieldlarda search yaparak pagination işlemini elastic searchd üzerinde yapacağız. MySql bizim persistence veritabanımız olacak ve onun üzerinde sadece  save,update ve getById işlemleri yapılabilecek. Elastic search üzerinde ise sadece full-text search yapacağız. Burada diyelimki elastic search insatncemiz down oldu. ozaman bizim MySql persistence dbsinden dataları tekrar elastic search üzerinde indexleyecek bir yapı kurmamız gerekir.