Gereksinimler ve Ön Hazırlık
Başarılı bir kurulum için sisteminizde Node.js (güncel LTS sürümü) ve Elasticsearch'ün 8.x veya üzeri bir sürümünün yüklü olması gerekmektedir. Elasticsearch, Java tabanlı bir arama motoru olduğu için sisteminizde uygun bir Java Runtime Environment (JRE) bulunmalıdır.
Projenizi başlatmak için bir dizin oluşturun ve gerekli kütüphaneleri yükleyin. Elasticsearch ile iletişim kurmak için resmi @elastic/elasticsearch istemcisini kullanacağız.
npm init -y
npm install @elastic/elasticsearch express dotenv
Bu komutlar, projenizi başlatacak ve gerekli bağımlılıkları yükleyecektir. express kütüphanesini, arama sonuçlarını sunacak API uç noktalarını oluşturmak için kullanacağız.
Elasticsearch İstemcisini Yapılandırma
Elasticsearch istemcisini projenize dahil etmek ve güvenli bir şekilde bağlanmak, uygulamanızın kalbidir. Bağlantı bilgilerini doğrudan kod içine yazmak yerine, bir .env dosyası kullanarak yönetmek en iyi güvenlik pratiklerinden biridir.
// .env dosyası
ELASTICSEARCH_URL=http://localhost:9200
Aşağıdaki kod bloğu ile Elasticsearch istemcisini başlatıyoruz. İstemciyi tek bir modül olarak tanımlamak, uygulamanın geri kalanında bağlantıyı tekrar tekrar oluşturmanızı engeller.
const { Client } = require('@elastic/elasticsearch');
require('dotenv').config();
const client = new Client({
node: process.env.ELASTICSEARCH_URL,
auth: {
username: 'elastic',
password: 'sifreniz' // Üretim ortamında güvenli yönetilmelidir
}
});
module.exports = client;
Bu yapılandırma, uygulamanızın Elasticsearch sunucusu ile güvenli bir şekilde konuşmasını sağlar. Bağlantı hatalarını ayıklamak için istemciyi başlatırken bir ping komutu ile sunucunun ayakta olup olmadığını kontrol etmeniz önerilir.
Veri İndeksleme ve Mapping Stratejileri
Elasticsearch'e veri göndermeden önce, verinin nasıl saklanacağını belirleyen "Mapping" (şema) yapısını oluşturmalısınız. Doğru bir mapping, arama performansını doğrudan etkiler. Örneğin, metin alanları için text, tam eşleşme gerektiren alanlar için keyword tipi kullanılmalıdır.
async function createIndex() {
await client.indices.create({
index: 'urunler',
body: {
mappings: {
properties: {
ad: { type: 'text' },
kategori: { type: 'keyword' },
fiyat: { type: 'float' },
eklenmeTarihi: { type: 'date' }
}
}
}
});
}
Bu kod bloğu, 'urunler' adında bir indeks oluşturur. text tipi, metin üzerinde arama yapılmasına izin verirken, keyword tipi filtreleme ve gruplama (aggregation) işlemleri için optimize edilmiştir.
Dikkat: Üretim ortamında indeks şemalarını dinamik olarak oluşturmak yerine, uygulama başlangıcında veya göç (migration) scriptleri ile sabit tutmak, veri tutarlılığı açısından kritiktir.
Gelişmiş Arama Sorguları Oluşturma
Kullanıcılar arama kutusuna bir terim girdiğinde, Elasticsearch'ün multi_match sorgusunu kullanarak birden fazla alanda arama yapabiliriz. Bu, kullanıcı deneyimini artırır çünkü kullanıcı hem ürün adında hem de açıklamasında arama yapabilir.
async function aramaYap(terim) {
const result = await client.search({
index: 'urunler',
query: {
multi_match: {
query: terim,
fields: ['ad', 'kategori'],
fuzziness: 'AUTO' // Yazım hatalarını tolere eder
}
}
});
return result.hits.hits;
}
fuzziness: 'AUTO' parametresi, kullanıcının yaptığı küçük yazım hatalarını (örneğin "bilgisayr" yerine "bilgisayar") Elasticsearch'ün otomatik düzeltmesini sağlar.
Veri Performansı Karşılaştırması
Arama motoru seçerken veya yapılandırırken aşağıdaki tablo, yöntemlerin avantaj ve dezavantajlarını anlamanıza yardımcı olacaktır.
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| SQL LIKE | Basit, ek kurulum gerektirmez | Büyük veride çok yavaştır |
| Elasticsearch | Çok hızlı, gelişmiş analiz yeteneği | Ek altyapı ve bakım gerektirir |
| MongoDB Text Search | Kolay entegrasyon | Elasticsearch kadar esnek değil |
Hata Yönetimi ve Güvenlik Uyarıları
Arama motorunuzu dış dünyaya açarken, kullanıcıdan gelen veriyi doğrudan sorguya dahil etmeyin. Bu, "Elasticsearch Injection" riskine yol açabilir. Her zaman girdileri temizleyin ve doğrulayın.
Güvenlik Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Uygulamanızı yayına almadan önce tüm API uç noktalarınızı bir yetkilendirme katmanından (JWT vb.) geçirdiğinizden ve kullanıcı girdilerini (input validation) doğruladığınızdan emin olun.
Sıkça Sorulan Sorular
Elasticsearch neden SQL'den daha hızlı?
Elasticsearch, "Inverted Index" (Ters Dizin) yapısını kullanır. Bu yapı, bir kitabın sonundaki indeks sayfası gibidir; kelimenin hangi dokümanlarda geçtiğini önceden bildiği için tüm tabloyu taramak yerine doğrudan ilgili dokümanlara gider.
Fuzziness parametresi ne işe yarar?
Kullanıcıların arama yaparken yaptığı harf hatalarını veya eksiklerini tolere ederek, arama sonuçlarının boş dönmesini engeller ve kullanıcı deneyimini iyileştirir.
Üretim ortamında cluster yönetimi nasıl olmalı?
En az 3 düğümlü (node) bir cluster yapısı, yüksek erişilebilirlik ve veri yedekliliği için standart kabul edilir.
İndeksleme sırasında verilerim neden hemen görünmüyor?
Elasticsearch, performans için verileri "refresh" aralıklarıyla indeksler. Varsayılan değer genellikle 1 saniyedir. Eğer anlık görünürlük gerekiyorsa, sorgu parametrelerinde refresh=true kullanılabilir ancak bu performansı olumsuz etkileyebilir.
Node.js ile hangi kütüphaneyi kullanmalıyım?
Resmi @elastic/elasticsearch kütüphanesi, TypeScript desteği, tip güvenliği ve güncel API uyumluluğu nedeniyle tek tercihiniz olmalıdır.
Elasticsearch'te Aggregations ile Faceted Search (Filtreleme) Geliştirme
Modern bir e-ticaret uygulamasında kullanıcılar sadece arama yapmakla kalmaz, aynı zamanda sonuçları kategori, fiyat aralığı veya marka gibi kriterlere göre daraltmak isterler. Elasticsearch'ün Aggregations özelliği, verileri gruplandırarak bu tür filtreleme menülerini oluşturmak için mükemmel bir araçtır.
Aşağıdaki örnek, bir ürün arama sorgusunda "kategori" bazlı gruplandırma yapmayı göstermektedir:
const result = await client.search({
index: 'products',
body: {
query: { match: { description: 'akıllı telefon' } },
aggs: {
categories: {
terms: { field: 'category.keyword' }
},
avg_price: {
avg: { field: 'price' }
}
}
}
});
console.log(result.aggregations.categories.buckets);
Bu sorgu sonucunda, aranan terimle eşleşen ürünlerin hangi kategorilerde kaçar adet bulunduğu bilgisini alırsınız. Bu veriyi ön yüzde dinamik bir "filtreleme paneli" oluşturmak için kullanabilirsiniz.
Elasticsearch Performansını İzleme ve Hata Ayıklama
Üretim ortamında arama motorunuzun yavaşlaması, kullanıcı deneyimini doğrudan etkiler. Elasticsearch'te performans darboğazlarını tespit etmek için Profile API kullanılmalıdır. Bu API, sorgunuzun hangi aşamada (rewrite, collect, score) ne kadar süre harcadığını detaylı bir şekilde raporlar.
Sorgu Profilleme Nasıl Yapılır?
Sorgularınıza profile: true parametresini ekleyerek, sorgunun arka planda nasıl işlendiğini analiz edebilirsiniz:
const response = await client.search({
index: 'products',
body: {
profile: true,
query: {
match: { name: 'laptop' }
}
}
});
// Sorgu çalışma detaylarını inceleyin
console.log(JSON.stringify(response.profile, null, 2));
Yaygın Performans Sorunları ve Çözümleri
- Shard Sayısı: Çok fazla shard (parça), küçük veri setlerinde gereksiz overhead yaratır. Veri boyutunuza göre shard sayısını optimize edin.
- Mapping Optimizasyonu: Metin alanlarında
textvekeywordtiplerini doğru kullanın. Gereksiz alanlardaindex: falsekullanarak indeks boyutunu küçültün. - Wildcard Sorguları: Başında joker karakter olan sorgular (
*kelime) çok maliyetlidir. Mümkünsen-gramveyaedge_ngramtokenizer'larını tercih edin.
İleri Seviye İpucu: Index Alias Kullanımı
Sıfır kesinti (Zero-downtime) ile indeks güncellemesi yapmak istiyorsanız Index Alias (Takma Ad) yapısını kullanmalısınız. Bu yöntem, uygulamanızın her zaman güncel veriye erişmesini sağlarken, arka planda yeni bir indekse veri aktarmanıza olanak tanır.
// Yeni bir indeks oluşturun
await client.indices.create({ index: 'products_v2' });
// Alias'ı eski indeksten yeniye taşıyın
await client.indices.updateAliases({
body: {
actions: [
{ remove: { index: 'products_v1', alias: 'products' } },
{ add: { index: 'products_v2', alias: 'products' } }
]
}
});
Bu strateji, özellikle büyük ölçekli veri göçlerinde veya mapping değişikliklerinde uygulamanızın arama özelliğinin kesintisiz çalışmasını garanti eder.
Sonuç
Node.js ve Elasticsearch ikilisi, modern web uygulamaları için en güçlü arama çözümlerinden biridir. Bu rehberde, temel bağlantıdan gelişmiş arama sorgularına kadar geniş bir yelpazeyi ele aldık. Bir sonraki adım olarak, Elasticsearch'ün sunduğu "Aggregations" (Gruplandırma) özelliğini kullanarak e-ticaret siteleri için "Faceted Search" (Filtreleme menüleri) yapısını projenize entegre etmeyi deneyebilirsiniz. Başarılı bir arama motoru, sadece doğru sonucu bulmak değil, aynı zamanda kullanıcıyı o sonuca en hızlı şekilde ulaştırmaktır.


Yorumlar (0)
Yorum Yaz