ElasticSearch Kullanımı
Husamettin Elalmis
Merhaba arkadaşlar, bu yazıda sizlere ElasticSearch kullanımından bahsedeceğim,
ElasticSearch Nedir?
ElasticSearch, Lucene alt yapısı üzerine kurulmuş, Java programlama dili ile open-source olarak geliştirilmiş, ölçeklenebilir, full text search tabanlı bir search engine dir.
Elasticsearch, verileri JSON tipinde saklar.
Elasticsearch üzerinde verilerimizi indexlerken, ilgili dokümanın yanı entitynin her propertysini indexlememeliyiz. ElasticSearch sadece search işlemlerimizi hızlı bir şekilde yapabilmemizi sağlayan bir araçtır, veritabanı değildir.
Tarihçesi
En populer search engine sistemlerinden olan Lucene zamanında sıkça kullanılmıştır.
Lucene versiyonu 1.x vardı o zamanlar, seneler önce Dış İşleri Bakanlığı .Net projesinde bizzat arama işlemlerinde kullanılıyordu, ana sayfada tüm personel üzerinde arama yapmak için kullanılıyordu. Oldukça performanslıydı.
Daha sonrasında 2.x versiyonu çıktı, tüm namespace ve komutlar tamamen değişti. Eski lucene ve yeni lucene olmak üzere ayrı ayrı kullanılmaya başlandı.
Lucene implementasyonu, MSSQL queryler üzerine yapılandırılan indexleme motoru idi. Lucene, kendi başına çalışan bağımsız bir framework kütüphanesidir. Query bazında hangi alanların indexleneceğini filan belirtiyorduk.
Lucene alt yapısı üzerine kurulmuş olan ElasticSearch, günümüzde son versiyonu 7.x olarak kullanılmaktadır.
7.x ve öncesi tüm namespaceler ve komutlar tamamen farklıdır.
7.x ve sonrası tüm namespaceler ve komutlar tamamen farklıdır.
Hangi sürümde ElasticSearch yapılandırılacağı bu yüzden önemlidir. Eski kodlar yeni sistemlerde Refactoringe gitmek zorundadır.
Lucene olsun, ElasticSearch olsun, milyon satırdan oluşan indexlenmiş yapılarda çok hızlı result alınmasını sağlamaktadır. Lucene zamanında bunu gözümle gördüm teyid ettim. Normal şartlarda çalıştırılan sql querylerden kat ve kat daha hızlı response veriyor idi. ElasticSearch'de bu durumu henüz deneyimlemedim, bu konuda henüz bir çalışmam olmamıştır.
Nerelerde Kullanılabilir?
Milyon satırlık log dosyalarında arama yapan sistemlerde kullanılabilir
Milyon satırlık TCKimlik sorgulama işlemlerinde kullanılabilir.
Coğrafi bilgi sistemleri yapılarında kullanılabilir (koordinat sistemleri, yer bulma, konum bulma, area-bölge bulma vb. data search işlemleri)
Bu ve buna benzer "hızlı ara ve bul" senaryosuna ilişkin heryerde kullanılabilir.
İçişleri Bakanlığı projesinde şu an aktif olarak Log verilerinin indexlenmesinde kullanıldığı görülmüştür.
Yararlanılan Kaynaklar
Kurulum
https://www.elastic.co/downloads/elasticsearch adresinden windows versiyonu zip olarak indirilir ve extract edilir. Elasticsearch.bat dosyası çalıştırılır.
Elasticsearch.bat çalıştırıldığında bu şekilde console görünür, uygulamamız boyunca bu açık kalmalıdır.
http://localhost:9200 adresi üzerinden ElasticSearch'in durumuna ulaşabiliyoruz. Kullanılan version bilgisini buradan görebiliriz.
https://chrome.google.com/webstore/detail/elasticsearch-head/ffmkiejjmecolpfloofpjologoblkegm adresinden chrome extensionu yükleyebiliriz. Bu bize, Elasticsearch indexlerini yönetmeyi sağlayan web arayüzünü gösterir. (alternatifi Kibana'dır.)
Terminoloji
Veritabanı ile Elasticsearch terimlerini birbirine benzetirsek şöyledir,
Database => Index
Table => Type
Row => Document
Column => Field
Schema => Mapping
Örnek Proje Yapısı
Elasticsearch, nugetpackage olarak kurulur. 7.x sürümünü kurdum.
Dummy Data Hazırlanması
ElasticSearchArge dbsi oluşturdum.
t_Rehber isimli tablo oluşturdum
ArksoftUI tool aracı Randomizer kullanarak 1000 adet t_Rehber tablosuna uygun olacak rastgele veri ürettim
ArksoftUI tool aracı Tilda kullanarak dumy data kümesinden insert scripti ürettim
Oluşturulan insert scriptini MSSQLde run ettim
1000 adet veri seti t_Rehber tablosunda mevcut.
AppDbContext.cs
using ElasticSearchArge.ConsoleCore.Model;
using Microsoft.EntityFrameworkCore;
namespace ElasticSearchArge.ConsoleCore.Data
{
public
class
AppDbContext : DbContext
{
protected
override
void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlServer(“Data Source=.; Initial Catalog=ElasticSearchArge; Persist Security Info=True; Integrated Security=SSPI;pooling=true;”);
}
public DbSet<t_Rehber> t_Rehber { get; set; }
}
}
t_Rehber.cs
namespace ElasticSearchArge.ConsoleCore.Model
{
public
class
t_Rehber
{
public
int Id { get; set; }
public
long? TCKN { get; set; }
public
string Ad { get; set; }
public
string Soyad { get; set; }
public
string CepTel { get; set; }
}
}
Program.cs
using ElasticSearchArge.ConsoleCore.Data;
using ElasticSearchArge.ConsoleCore.Model;
using Nest;
using System;
using System.Linq;
namespace ElasticSearchArge.ConsoleCore
{
static
void Main(string[] args)
{
Console.WriteLine(“== ElasticSearch Arge ==”);
// yapılandırma ayarı
ConnectionSettings conSettings = new ConnectionSettings(new Uri(“http://localhost:9200/”))
.DefaultIndex(“defaultIndex”)
.DefaultMappingFor<t_Rehber>(m => m.IndexName(“rehber_alias”));
// elasticsearch client objesi
ElasticClient client = new ElasticClient(conSettings);
CreateIndex(client);
//PerformSearch01(client);
//PerformSearch02(client);
Console.WriteLine(“ok”);
Console.ReadLine();
}
// CreateIndex – Index oluştur
public
static
void CreateIndex(ElasticClient client)
{
using (AppDbContext context = new AppDbContext())
{
// dbden t_Rehber dataların tümünü çek
var list = context.t_Rehber.ToList();
// alias belirle
var alias = “rehber_alias”; // elasticsearch aliaslar ile ilgileniyor
if (!client.Indices.Exists(alias).Exists) // index yok ise oluştur
{
var response = client.Indices.Create(alias, index => index.Map<t_Rehber>(x => x.AutoMap()));
}
// dbdeki kayıtların listesini bulkInsert listesine at
var bulkInsert = new BulkDescriptor();
foreach (var document in list)
{
bulkInsert.Index<t_Rehber>(i => i
.Document(document)
.Id(document.Soyad)
.Index(“rehber_alias”));
}
// bulk listesini indexe bas
client.Bulk(bulkInsert);
Console.WriteLine(“Index oluşturuldu”);
}
}
// PerformSearch01 – Match kullanım örneği
public
static
void PerformSearch01(ElasticClient client)
{
// TCNOya göre tek kayıt getir
var searchResponse = client.Search<t_Rehber>(s => s
.Query(q => q
.Match(m => m
.Field(f => f.TCKN)
.Query(“61514429596”)
)
)
);
foreach (var item in searchResponse.Documents)
{
Console.WriteLine($”TC:{item.TCKN} Ad:{item.Ad} Soyad:{item.Soyad} Cep:{item.CepTel}“);
}
}
// PerformSearch02 – Wildcard kullanım örneği
public
static
void PerformSearch02(ElasticClient client)
{
// soyadı a ile başlayanları getir
var searchResponse = client.Search<t_Rehber>(s => s
.Query(q => q
.Wildcard(c => c
.Boost(1.1)
.Field(p => p.Soyad)
.Value(“a*”)
.Rewrite(MultiTermQueryRewrite.TopTermsBoost(10))
)).From(0).Size(50) // ilk 50 kaydı getir
);
foreach (var item in searchResponse.Documents)
{
Console.WriteLine($”TC:{item.TCKN} Ad:{item.Ad} Soyad:{item.Soyad} Cep:{item.CepTel}“);
}
}
}
CreateIndex çıktısı
UI üzerinden sorgulama yapılabilmektedir
PerformSearch01 çıktısı
Perform02 çıktısı
Sonuç
Elasticsearch, son derece hızlı query yapabilmektedir. Dönüş hızları, normal db querylerinin çok üzerindedir.
Elasticsearch, başlı başına bir araçtır. Üzerinde çalışmayı ve uzmanlaşmayı gerektirir. Kullanılabilecek daha bir çok arama kriteri, boost ayarları, analizler vb. gibi işlevleri vardır.
Syntax dili karmaşıktır, ilk etapda zorluk çekilebilir, sonrasında mantığı kavranırsa kodlama tarafı da hızlanır.
Belki bir gün bir şekilde işimiz düşer kullanırız, belli olmaz
Saygılarımla,
Hüsamettin ELALMIŞ – 28.06.2021
husamettin.elalmis@arksoft.com.tr
Last updated