Kibana Query Language (KQL), Kibana uygulamasında kullanılan bir sorgulama dilidir. Bu dil, Kibana uygulamasındaki Discover bölümünün en temel bileşenidir. KQL sayesinde Elasticsearch üzerindeki index’lerde basit bir şekilde arama işlemleri gerçekleştirilebilmektedir. Yazılan basit sorgular, arka planda otomatik olarak Elasticsearch DLS query formatına dönüştürülerek aramalar yapılmaktadır.
Karmaşık Elasticsearch DSL sorguları tek bir satırda basit bir şekilde KQL ile gerçekleştirilebilmektedir.
KQL free text search
Her bir kelimeyi ayrı ayrı arayıp bulmak için kelimeler arasında boşluklar bırakılarak yapılan aramalardır. Örneğin içinde apple veya banana geçen dokümanları elde etmek için aşağıdaki gibi aralarında boşluklar bırakarak arandığında ilgili Elasticsearch DSL sorgusu üretilecektir. Free text search, elastic tarafında multi_match türünde bir filter uygular. Dokümandaki tüm alanlarda ilgili kayıtların aranması sağlanır. Bunu sağlayan “best_fields” parametresidir.
Bu tür aramalarda, ilgili metin tırnak içinde aratılarak ilgili kelime veya cümle ile tam eşleşen dokümanlar aranmaktadır. Bunu sağlayan “phrase” parametresidir. Örneğin “apple banana” araması yapıldığında, doküman alanlarında aranan metni aynı şekilde arar. apple ve banan şeklinde ayırıp aramaz.
Elasticsearch üzerinde null değerler index üzerine eklenemez ve aranamaz. Yani property değeri null olan kayıtları getirmek için bir sorgu yazdığınızda doğru cevap alınamaz. Bir alan null olarak girildiğinde, o alanın değeri yokmuş gibi değerlendirilir. Bir alan boş bir dizi olarak girildiğinde de yokmuş gibi değerlendirilir.
Örneğin, aşağıdaki sorguda, name değeri null olan kayıtlar alınamaz.
Burada, null olarak gelen name değerleri, “NULL” ile değiştirilmiştir. Bu sayede NULL şeklinde arama yapmak mümkün hale gelmektedir. Aşağıdaki şekilde yeni değerler eklendiğinde;
PUT products-idx/_doc/1
{
"name": null
}
PUT products-idx/_doc/1
{
"name": []
}
Boş diziler null değere sahip olmadığı için “NULL” ile değiştirilmez. Bu sorgunun sonucunda 1 numaralı doküman elde edilir ancak 2 numaralı doküman elde edilemez.
Not: null_value değeri alan veri tipi ile uygun olmalıdır. Örneğin long tipinde bir alana string tipinde null_value değeri atanamaz.
Elasticsearch üzerinde indeksler için iki tür mapping oluşturma yöntemi vardır. Bunlar;
Dynamic mapping (Dinamik Eşleştirme)
Explicit mapping (Önceden Belirlenen Eşleştirme)
Dynamic Mapping (Dinamik Eşleştirme)
Bir kullanıcı yukarıdaki örnekte olduğu gibi mapping tanımını önceden yapmadığında, Elasticsearch eşlemeyi varsayılan olarak gerektiği gibi oluşturur veya günceller. Bu dinamik eşleştirme (dynamic mapping) olarak bilinir.
Dinamik eşleştirmede, alan tipleri veri içeriğinden çıkarılmaktadır. Bu noktada eğer index oluşturulurken girilen verilerden biri sayısal olarak girilmişse ve başka verilere göre metinsel değerler de alabilecek durumdaysa, örneğin float olarak oluşturulan bir alana metinsel bir ifade yazılmaya çalışıldığında hata oluşacaktır.
Dinamik eşleme ile Elasticsearch her alana bakar ve alan içeriğinden veri türünü çıkarmaya çalışır. Ardından, her alana bir tür atar ve eşleme olarak bilinen alan adları ve türlerin bir listesini oluşturur.
Atanan alan türüne bağlı olarak, her alan dizine alınır ve farklı istek türleri (full text search, aggregations, sorting) için hazırlanır. Bu nedenle eşleştirme, Elasticsearch’ün verileri nasıl depoladığı ve aradığı konusunda önemli bir rol oynar.
Bir indekse ait mapping değerlerine ulaşmak için şu sorgu çalıştırılabilir.
Mapping JSON verisi içerisinde, indeksteki alanların adlarının ve türlerinin bir listesini bulunur. Elasticsearch alan türleri (field types) bilgilerine detaylı olarak buradan ulaşılabilir.
Metin İndeksleme
Metinsel alanlar için iki farklı tür bulunur:
Text field
Keyword field
Varsayılan olarak, her string, metin (text) alanı ve anahtar kelime (keyword) çoklu alanı olarak iki kez eşlenir. Her alan türü, farklı istek türleri için hazırlanır.
Text alan türü, full-text search yapabilmek için tasarlanmıştır.
Keyword alan türü, kesin aramalar (exact searches), toplamlar (Aggregations) ve sıralamalar (sorting) için tasarlanmıştır.
Text Field (Metin Alanlar)
Metin Analizi
Elasticsearch’te arama yaptığınızda, büyük/küçük harfe duyarlı olmadığını veya noktalama işaretlerinin önemi yoktur. Bunun nedeni, veriler indekse eklendiğinde, metin analizinin gerçekleşmesidir.
Varsayılan olarak, metinler indekse alındığında analiz edilir. Metin, belirteçler (token) olarak da bilinen ayrık sözcüklere bölünür. Çözümleyici (analyzer), her kelimeyi küçük harflere dönüştürür ve noktalama işaretlerini kaldırır.
Analiz sonucunda ortaya çıkan metinler, bir inverted index tablosuna kaydedilir.
Bu işlem, indekse her doküman eklendiğinde tekrarlanır. Zamanla inverted index tablosu aşağıdaki gibi değişikliğe uğrar.
Bu durumda, “this book” şeklinde bir arama yapıldığında, arama sonucunda 1,2,3 numaralı dokümanlar bulunur.
Keyword Field (Anahtar Alanlar)
Keyword alanlar, kesin aramalar, toplamlar ve sıralamalar için kullanılır. Aranan değerlerde, ilgili dokümanın sahip olduğu değerleri bulmak için doküman kimliğini tarar
PUT fruits/_doc/1
{
"country": "İstanbul"
}
PUT fruits/_doc/2
{
"country": "Ankara"
}
PUT fruits/_doc/3
{
"country": "Manisa"
}
PUT fruits/_doc/4
{
"country": "Trabzon"
}
PUT fruits/_doc/5
{
"country": "Van"
}
PUT fruits/_doc/6
{
"country": "Antalya"
}
PUT fruits/_doc/7
{
"country": "Bolu"
}
Elasticsearch sizin için dinamik olarak bir eşleme oluşturduğunda, bir metni ne için kullanmak istediğinizi bilemez, bu nedenle tüm metinleri her iki alan türüne eşler. Örneğin vendor alanı:
Her iki alan türüne de ihtiyacınız olmadığı durumlarda, disk alanları israf edilmiş olur. Çünkü inverted index kullanımına gerek olmayan durumlarda gereksiz yere inverted index alanları oluşturulmuş olur.
Explicit Mapping (Önceden Belirlenen Eşleştirme)
Mapping (tip eşleştirme) işlemini kendiniz tanımlamak istediğiniz durumlarda, bunu index oluşturma sırasında yapabilirsiniz. Bu sayede eşleştirme tanımını kendiniz tasarlayabilirsiniz. Örneğin:
Hangi metinsel alanların Full-text search alanları olarak ele alınacağını belirtebilirsiniz.
Hangi alanların sayı, tarih veya geolocation olacağını belirtebilirsiniz.
Tarih alanlarının biçimini belirtebilirsiniz.
Kaynak kullanımını ve performansı dengelemek için çalışma zamanı alanlarını (runtime fields) indekse alınmış alanlarla birlikte kullanabilirsiniz. Index daha küçük olacaktır, ancak arama performansı daha yavaş olacaktır.
Her index için tek bir eşleştirme (mapping) belirlenir. İndeks oluşturulduktan sonra, bir eşlemeye yalnızca yeni alanlar eklenebilir. Mevcut bir alanın eşleşmesi değiştirilemez. Eğer mevcut bir alanın türünün değiştirilmesi gerekiyorsa, istenen eşlemeyle yeni bir indeks oluşturulur ve ardından tüm dokümanlar yeni dizine yeniden aktarılır.
Field tanımlamaları properties içerisinde belirtilmektedir. Her field için ad ve tip belirtilmektedir. Kendi oluşturduğunuz eşleştirmelerde gereksiz alan tanımlamalarını iptal ederek optimum bir indeks oluşturabilirsiniz. Oluşturduğunuz indekslerde, alanlara istediğiniz analyzer atamalarını yapabilirsiniz.
Dikkat
Bir indekste çok fazla alan tanımlamak, yetersiz bellek hatalarına ve kurtarılması zor durumlardan kaynaklanabilecek bir eşleme patlamasına neden olabilir. Eklenen her yeni belgenin dinamik eşleme gibi yeni alanlar sunduğu bir durumu düşünün. Her yeni alan, indekste mapping olarak eklenir ve mapping büyüdükçe bir sorun haline gelebilir. Bu durumlara karşı Elasticsearch ayarlarında “mapping limit settings” kullanılarak, mapping alan sayısı sınırlandırılabilir.