Elasticsearch: Güçlü Veri Sorgulama Teknikleri [4/5]
Elasticsearch: Powerful Data Querying Techniques [4/5]
Term-level queri̇es, Full-text queri̇es ve Compound and aggregation queries, bilgi erişiminde temel kavramlardır. Term-level queri̇es belirli terimlerle ilgili aramalarda, full-text queri̇es geniş kapsamlı araştırmalarda etkilidir. Compound and aggregation ise farklı sorgu tiplerini birleştirerek özelleştirilmiş sonuçlar sağlar. Bu konular, bilgi yönetimi ve erişiminde stratejiler sunar. Bu makalede, temel sorgu türlerinin önemi ve kullanım alanlarına odaklanarak, etkili araştırma yöntemlerini ele alacağız.
Diğer Elasticsearch makalelerine linkler üzerinden erişebilirsiniz.
1- Term-Level Queries
Yapılandırılmış verilerdeki (tarih aralıkları, IP adresleri, fiyatlar veya ürün id (kimlik) kesin değerleri temel alan belgeleri bulmak için terim düzeyinde sorguları kullanılabilir. Full-text search’den farklı olarak term-level sorgular, arama terimlerini analiz etmez. Bunun yerine terim düzeyindeki sorgular, bir alanda depolanan terimlerle tam olarak eşleşir.
Term-level sorgularda structured veriler üzerinde (kesin değerler) iki tarih arası veya id’ye göre arama şeklinde direkt arama yapılabilmektedir. İlişki değeri olmadığı için burada skor değeri bulunmamaktadır. Örneğin ‘Istanbul’da oturan kullanıcıları getir’ cityNumber == 34
dediğimizde tam olarak eşleşen kullanıcıları getirecektir.
Term-level query türünde analiz süreci (tokenization ve normalization) yoktur fakat full-text query türünde analiz süreci vardır.
Term-level query büyük/küçük harf duyarlılığına (case sensitive) sahiptir.
Denizbank
olarak kaydedilmiş veriyidenizbank
olarak küçük harf ile aranırsa sonuç alınamaz.
1.1 — Term Query
Belirtilen alandaki tam eşleşmeyi kontrol eder. Fiyat, ürün id veya kullanıcı adı gibi kesin bir değere dayalı olarak belgeleri bulmak için terim sorgusu kullanılabilir.
{
"query": {
"term": {
"company_name.keyword": {
"value": "Intertech",
"case_insensitive": true
}
}
}
}
company_name.keyword
sonunda keyword ifadesi yer almaktadır. Çünkü company_name alanına text
ve keyword
olmak üzere 2 adet tip ataması gerçekleştirilmiştir. Yukarıdaki sorguda keyword tipi üzerinden arama yapılmak istenildiği için keyword ile beraber belirtilmektedir.
Parametre isminin sonunda yer alan keyword aslında takma isim olup herhangi bir kelime (key, test, cihat, denizbank vb.) olabilir. Ancak best practices açısından isimlendirmeler önemlidir.
1.2 — Terms Query
Belirli bir alanda birden çok terimi eşleştirmek için kullanılan bir sorgu türüdür. Örneğin şirket adı Intertech
veya Denizbank
olanları listelemek gibi birden farklı değer ile arama yapılmak istenildiğinde kullanılabilir.
{
"query": {
"terms": {
"company_name.keyword": ["Intertech", "Denizbank"]
}
}
}
Yukarıdaki sorgu, belirtilen alandaki değerler arasında herhangi bir terimin bulunduğu belgeleri getirecektir.
1.3 — IDs Query
Belirli bir belge kimliği veya bir dizi belge kimliği üzerinde sorgulama yapmak için kullanılan bir sorgu türüdür. Bu sorgu, belirtilen belge kimlikleri ile eşleşen belgeleri getirir.
{
"query": {
"ids": {
"values": [
"gilUkYsBtQJw_l-qgx_s",
"qylUkYsBtQJw_l-qgx_t"
]
}
}
}
Bu sorgulama türü ID değerine göre kurgulanmış özel arama türüdür. Kaydedilen belgelerin ID değerine göre arama yapılabilir.
1.4 — Exist Query
Belirli bir alanın var olup olmadığını kontrol etmek için kullanılan bir sorgu türüdür. Bu sorgu, belirtilen bir alanın değerine bakmaksızın, yalnızca belgenin bu alanı içerip içermediğini kontrol eder.
Örneğin bank_name
alanının var olup olmadığını kontrol eder. Çünkü NoSQL veri tabanlarında satırlar arasındaki field sayısının eşit olmasına gerek yoktur. Bir satırda 5 field, başka bir satırda 7 field olabilir. Dolayısıyla field var mı? yok mu? kontrolü yapılabilir.
{
"query": {
"exists": {
"field": "bank_name"
}
}
}
1.5 — Prefix Query (StartWith)
Belirli bir alanın değerine sahip belgeleri bulmak için bir önek (başlangıç) terimi kullanarak sorgu yapma yöntemidir. Bu sorgu, belirtilen alanın belirli bir önek ile başlayan değerlere sahip belgeleri getirir.
Tam bir değer üzerinden sorgulama yapmayıp, belirli karakterler ile başlayan verileri getirir. Örneğin aşağıdaki sorguda deniz
ile başlayan banka isimlerini listeleyecektir.
{
"query": {
"prefix": {
"bank_name.keyword": {
"value": "deniz",
"case_insensitive": true
}
}
}
}
1.6 — Range Query
Belirli bir aralıktaki değerlere sahip belgeleri bulmak için kullanılan bir sorgu türüdür. Bu sorgu, belirtilen bir alanın değeri belirli bir aralıkta olan belgeleri filtrelemek için kullanılır.
Tipi keyword ya da text olan fieldlarda böyle bir kullanım sergileyemezsiniz.
{
"query": {
"range": {
"taxless_total_price": {
"gte": 20.50,
"lte": 40.00
}
}
}
}
1.7 — WildCard Query
Belirli bir desene uyan terimlere sahip belgeleri bulmak için kullanılan bir sorgu türüdür. Wildcard, belirli bir deseni ifade etmek için joker karakterleri (genellikle * veya ?) kullanır.
Prefix sorgusunda belirlenen karakterle başlayan (startwith) sonuçları listelerken, Wildcard sorgusu ise herhangi bir konumda bulunan belirli karakterlerle ilgili esnek bir arama yapmamıza olanak tanır.
Asterisk (*) : Birden fazla karakter
? : Tek karakter
{
"query": {
"wildcard": {
"bank_name.keyword": {
"value": "Deni*",
"case_insensitive": true
}
}
}
}
1.8 — Fuzzy Query
Benzer ancak tam olarak eşleşmeyen terimleri bulmak için kullanılan bir sorgu türüdür. Bu sorgu, belirli bir terimdeki karakter değişikliklerine veya yazım hatalarına karşı toleranslıdır. Böylece benzer terimlere eşleşen belgeleri bulmanıza yardımcı olur.
Kullanıcı arama yaparken harf hatası yaptığında bu harf hatasını elasticsearch tolere ediyor. Normalde wildcard aramasında * (yıldız) dersek birden fazla karakteri, (? soru işareti) dersek 1 adet karakteri temsil ediyor. * karakterini dinamik yapmak istediğimizde fuzzy sorgularına ihtiyaç duyuyoruz.
{
"query": {
"fuzzy": {
"bank_name.keyword": {
"value": "enizbank", //Denizbank
"fuzziness": 1
}
}
}
}
Örneğin kullanıcı Denizbank
aramasında baştaki D
harfini unuttu. Search işleminde fuzziness değerini 1 (bir) belirleyerek başında herhangi bir harf olabileceğini vurgular ve uygun olan verileri listeleyebiliriz.
Örneğin bal
araması için (fuzziness: 1) kullanıcıya kal
, çal
, dal
, şal
, nal
gibi kelimeleri listelenir. Yani tek bir harf hatasına karşılık sonuçları getiriyor.
Fuzziness değeri belirlenmezse elasticsearch aranan kelimenin uzunluğuna göre otomatik fuzziness değeri belirler. Örneğin 5 karakterden fazla ise fuzziness değerini 2 olarak belirliyor.
Harf hatasının başta ya da sonda olması zorunda değildir, kelime ortasında da hata olabilir.
1.9 — Pagination Query
Tüm sorgular türlerinde (full-text search/term level query) kullanılabilir.
{
"from": 1,
"size": 5,
"query": {
"fuzzy": {
"customer_first_name.keyword": {
"value": "Stephanie",
"fuzziness": 0
}
}
}
}
1.10— Response Includes/Excludes (Select)
Herhangi bir arama yapıldığında veri tabanındaki tüm fieldlar listelenir. Ancak arama sırasında, source keyword’ü içerisinde include ve exclude yöntemiyle response’da sadece ihtiyaç olacak field’lar belirlenebilir.
{
"_source": {
"includes": [
"category",
"customer_first_name"
],
"excludes": [
"currency"
]
},
"from": 1,
"size": 5,
"query": {
"fuzzy": {
"customer_first_name.keyword": {
"value": "Stephanie",
"fuzziness": 0
}
}
}
}
1.11 — Sort Query (OrderBy)
Full-text search işleminde sıralama yapmak score değerine göre sıralanmış veriyi bozacağı için uygun değildir. Mümkün olduğunca sadece term-level sorgularda kullanılmalıdır. Çünkü full-text search işleminde dönen response sıralaması aranan kelime ile alaka düzeyine (score) göre sıralanmaktadır. Bunun üstüne ekstra bir sıralama yapmak uygun değildir.
{
"query": {
"term": {
"customer_gender": {
"value": "MaLE",
"case_insensitive": true
}
}
},
"sort": [
{
"taxless_total_price": {
"order": "desc"
},
"customer_first_name.keyword": {
"order": "asc"
}
}
]
}
Full-Text Queries
Elasticsearch, büyük veri setleri üzerinde (blog içerikleri, haber bildirimleri, word dosyaları vb.) etkili bir arama yapma imkanı sunan güçlü bir veri tabanıdır.
1.1 — Match Query
Belirli bir alan içinde belirli bir terimi aramak için kullanılan temel bir sorgu türüdür. Bu sorgu, belirtilen alan içindeki belgeleri belirli bir terim veya ifadeyle eşleştirmek için kullanılır.
Full-text search işlemi denildiğinde akıllara ilk gelecek kelime
match
olmalıdır.
{
"query": {
"match": {
"personal_full_name": "Cihat Solak"
}
}
}
//Operator belirtilmediği sürece OR anlamında sorgular. Cihat ya da Solak
Full-text işlemini makale başlık ve içeriklerinde veya haber içeriği/başlığı gibi hacimli veriler üzerinde kullanılmalıdır. Başlık gibi fieldlarda tip belirlenirken hem keyword
hemde text
olarak belirlemekte fayda vardır.
{
"query": {
"match": {
"personal_full_name": {
"query": "Cihat Solak",
"operator": "and"
}
}
}
}
Asıl olarak full-text arama avantajından yararlandığımız alanlar, “text” türünde olanlardır.
{
"query": {
"match": {
"personal_full_name": {
"query": "Cihat Solak",
"operator": "and",
"fuzziness": 2
}
}
}
}
Yukarıdaki sorgu gövdesini incelediğimizde
- Fuzziness ile 2 harf hatasının kabul edildiğini
And
operatörü ileCihat Solak
ifadesini birlikte ara, her ikisinin bulunduğunu nesneleri getir. YaniCihat Aran
ismindeCihat
geçiyor diye getirme.- Fuzziness değeri ne kadar yüksek belirlenirse, o derece ilgisiz veri listelenir. Dolayısıyla fuzziness değerini auto olarak ayarlamak iyidir.
Fuzziness değerini auto olarak belirlemek best practices açısından önem arz etmektedir.
Company Name: Intertech Information Technology and Marketing Inc.
// 1. Sorgu
{
"query": {
"match": {
"bank_name": "Intertech Information Technology and Marketing Inc."
}
}
}
// 2. Sorgu
{
"query": {
"match": {
"bank_name": "Technology and Marketing Inc."
}
}
}
// 3. Sorgu
{
"query": {
"match": {
"bank_name": "Marketing"
}
}
}
Yukarıdaki örneği incelediğimizde tüm sorgulamalarda Intertech Information Technology and Marketing Inc.
şirketi response’da yer alacak ancak skor değerinde farklılıklar yaşanacaktır.
Doktorlar Reçeteleri Neden Anlaşılmaz Bir Şekilde Yazarlar? başlığında bir match araması yaparken Reçete diye arama gerçekleştirdiğimizde sonuç alamayız. Reçeteleri şeklinde tam eşleşecek şekilde arama yapılmalıdır.
1.2 — Multi Match Query
Birden çok alanı aynı anda sorgulamak için kullanılan bir sorgu türüdür. Bu, belirli bir terimi veya ifadeyi birden çok alan içinde aramak için kullanışlıdır. Özellikle bir kullanıcının arama terimini birkaç farklı alan içinde eşleştirmek istediğinizde kullanılır.
{
"query": {
"multi_match": {
"query": "DenizBank",
"fields": [ "company_name", "address", "edge_plate", "title" ],
"operator": "or",
"fuzziness": "auto",
"type": "best_fields" //most_fields, cross_fields, phrase_prefix
}
}
}
1.3 — Match Bool Prefix Query
Aranılan metinde en sonda yer alan kelimeyi prefix olarak algılamaktadır. Sondaki kelime prefix ardından varsa diğer kelimeler OR
koşuluyla aranmaktadır. Prefix olarak belirlenen kelime hariç, diğer kelimelerde tam eşleşme beklemektedir.
Cihat Mesut So
ismindeki kullanıcıyı “Cihat Mesut So...” olarak aradığını düşünebiliriz. Cihat geçenler OR Mesut Geçenler OR So… geçenler. So
’dan sonra ne olursa…
{
"query": {
"match_bool_prefix": {
"personal_full_name": "Cihat Mesut So"
}
}
}
Formül: So… OR Mesut OR Cihat
Çıkan sonuçlarda SoLAKOĞLU olabilir ama So
ile başlaması gereklidir. Arkasından Cihat arkasından Mesut olabilir. So
ile başlayacak geri kalanı OR şeklinde devam edecek.
1.4 — Match Phrase Query
Öbek kelimeleri aramak için kullanılır. Örneğin Cihat Solak diye aradığınızda klasik match sorgusunda Cihat veya Solak geçenleri arar. Match Phrase olduğunda Cihat Solak geçenleri getirir ve sırası da önemlidir. İlk kelime cihat sonraki kelime solak olmak zorundadır.
{
"query": {
"match_phrase": {
"personal_full_name": "Cihat Solak"
}
}
}
Normalde şartlarda aramada “Cihat Solak” kelimesinin sıralamasının bir önemi yoktur. Yani “Cihat” kelimesi full name’in herhangi bir yerinde geçebilir. Eğer ki ben sıralı bir şekilde arama yapmak isteniliyorsa, birinci kelime “Cihat” ikinci kelime “Solak” olacak şekilde sırasının bir önemi varsa işte burada phrase query devreye giriyor. Yani bir cümleyi tam bir sıralama içerisinde arıyor.
match
aramasında kelimelerin sıralaması önemli değildir ancakmatch_phrase
sorgulamasında kelimeler tam sıraları olmalıdır. “Solak Cihat” kaydını bulamazdı çünkü sıralı sisteme uymuyor.
1.5 — Match Phrase Prefix Query
Aranılan kelimede en sonda yer alan kelimeyi prefix olarak algılamaktadır. Aranacak kelime ya da kelimelerin sıralaması önemlidir.
{
"query": {
"match_phrase_prefix": {
"personal_full_name": "Mehmet Yılmaz Arm"
}
}
}
Yukarıdaki aramanın sonucu aşağıdaki şekilde olabilir.
- Mehmet Yılmaz Armağan
- Mehmet Yılmaz Arm
- Ömer Mehmet Yılmaz Armay