iToverDose/Yazılım· 9 HAZIRAN 2026 · 04:02

SQLite FTS5'de Japonca arama sorununa basit çözüm

SQLite FTS5'in varsayılan ayarlarıyla Japonca metinlerde parçalı arama yaparken karşılaşılan gizli sorun ve sadece bir satırlık SQL komutu ile nasıl düzeltileceği. Veri tabanınızda Japonca, Çince ya da Korece içerik varsa okumaya devam edin.

DEV Community4 dk okuma0 Yorumlar

SQLite’in FTS5 (Full Text Search 5) özelliğini kullanarak kişisel notlarınızı, sohbet geçmişinizi ya da araştırma verilerinizi indekslemeye başladıysanız, varsayılan ayarların bazı dillerde beklenmedik sorunlara yol açtığını fark etmiş olabilirsiniz. Özellikle Japonca, Çince ya da Korece gibi boşluk kullanmayan dillerde, FTS5’in unicode61 tokenizer’ı metinleri parçalarken ciddi bir dezavantaja sahiptir. Bu ayar, İngilizce gibi boşlukla ayrılan dillerde çalışırken, Japonca metinlerde kelime parçalarını tanımakta zorlanır ve sonuçta arama sorgularının çoğunu yanıtsız bırakır.

Bu sorun genellikle ilk kez karşılaşılana kadar gizli kalır. Kullanıcılar haftalarca bir not uygulamasını ya da arama aracını kullandıktan sonra, Japonca içeriklerine ulaşamadıklarını ancak o zaman fark ederler. Neyse ki, bu sorunun çözümü sadece bir satırlık bir SQL komutu kadar basit. Ancak öncesinde, sorunun nasıl ortaya çıktığına ve neden bu kadar ince bir şekilde gizlendiğine daha yakından bakalım.

Japonca metinlerde neden arama yapılamıyor?

Varsayılan unicode61 tokenizer, metni kelime sınırlarına göre ayırır. İngilizce metinlerde bu sorun yaratmaz, çünkü kelimeler arasındaki boşluklar sayesinde her kelime ayrı bir token olarak indekslenir. Örneğin, "time blocking" gibi bir ifade, "time" ve "blocking" olarak iki ayrı token’a dönüştürülür ve her ikisi de aranabilir hale gelir.

Ancak Japonca gibi boşluk kullanılmayan dillerde durum farklıdır. "朝の運用フロー" (sabah operasyon akışı) gibi bir cümle, tek bir token olarak kaydedilir. Bu token, "朝の運用" (sabah operasyonu) ya da "午後" (öğleden sonra) gibi alt dizilerle arama yapıldığında hiçbir sonuç döndürmez, çünkü indekslenen token ile arama sorgusu birebir eşleşmez. Bu durum, sadece Japonca değil, Çince, Tayca ve benzeri dillerde de geçerlidir. Eğer veritabanınızda bu dillerde içerik varsa, varsayılan ayarlarla arama yaparken ciddi bir "geri çağırma" sorunu yaşıyorsunuz demektir.

Tek satırlık çözüm: Trigram tokenizer

Neyse ki, FTS5’in sunduğu alternatif tokenizer’lardan biri olan trigram, bu sorunu ortadan kaldırıyor. trigram tokenizer, metni her bir 3 karakterlik pencereye bölerek indeksler. Bu sayede, Japonca bir ifade olan "朝の運用フロー" indekslendiğinde aşağıdaki alt diziler oluşur:

朝の運 の運用 運用フ 用フロ フロー

Artık, "朝の運用" ya da "午後" gibi alt dizilerle yapılan aramalar bu indekslenen parçalarla eşleşeceği için doğru sonuçlar döndürür. Bu yöntem, kelime sınırlarına bağlı olmadığı için boşluk kullanılmayan dillerde de etkili bir şekilde çalışır.

Trigram kullanırken nelere dikkat etmek gerekir?

  • İndeks boyutu artar: Her satır, uzunluğu N olmak üzere, yaklaşık N-2 trigram girişiyle indekslenir. Gerçek veri kümelerinde bu, ham metin boyutunun 1.5 ila 2 katına denk gelir. Kişisel kullanım için bu artış sorun oluşturmazken, 100 GB’lık bir veri kümesi için daha dikkatli olmak gerekir.
  • Kısa sorgular sınırlıdır: Trigram aramaları en az 3 karakter gerektirir. Örneğin, "朝" (1 karakter) ya da "朝の" (2 karakter) gibi sorgular, daha yavaş ve verimsiz bir sorgulama planına geri düşer. Uygulama katmanında kısa sorguları filtrelemek önemlidir.
  • Sıralama (ranking) değişmez: BM25 gibi sıralama algoritmaları, trigram tokenizer kullanıldığında da etkisini korur. Örneğin, 800 belge arasında "mochi" kelimesini ararken en alakalı 5 belgeyi bulmak için kullanılan sıralama yöntemi aynı kalır.

FTS5’teki başka bir tuzak: "-" karakteri

FTS5’in varsayılan davranışında dikkat edilmesi gereken başka bir nokta da "-" (tire) karakterinin yol açtığı sorunlardır. Örneğin, "time-blocking" gibi bir ifade arandığında, tire karakteri aramanın başarısını etkileyebilir. Bu durum, özellikle "time-blocking" ya da "2024-06-15" gibi tire içeren sorgularla çalışırken dikkate alınmalıdır. Bu sorun, trigram tokenizer kullanıldığında da devam eder, bu yüzden uygulamada bu tür sorguları özel olarak işlemek gerekebilir.

Git + SQLite: Gerçek dünya uygulaması

Bu sorunla karşılaştıktan sonra, ben de kişisel bir bellek katmanı oluştururken bu çözümü uygulamaya karar verdim. Yaklaşık 800 adet Claude Code sohbet geçmişini indeksleyen bir sistem inşa ettim. Sistem, iki katmanlı bir mimariye sahip:

  • Git deposu (Kaynak doğruluğu): Tüm veriler JSON formatında, tarih sırasına göre depolanır. Bu dosyalar insan tarafından okunabilir, farklar incelenebilir ve yedeklenebilir niteliktedir. Verilerin kalıcı ve değiştirilemez olması gerektiği durumlarda Git, mükemmel bir kaynak doğruluğu sağlar.
  • SQLite indeksi (Hızlı arama): Verilerin indekslendiği SQLite FTS5 tablosu, sadece hızlı arama için kullanılır. Bu dosya .gitignore listesine eklenerek, gerektiğinde sıfırdan yeniden inşa edilebilir. Veritabanı bozulması, yanlışlıkla silinmesi ya da başka bir sorunla karşılaşılması durumunda, Git deposundan yeni bir indeks oluşturmak sadece bir komut kadar basit olur.

Sistem nasıl çalışıyor?

Her yeni olay (örneğin, bir karar ya da önemli bir not) aşağıdaki adımlarla işlenir:

  1. JSON dosyası olarak kaydet: Olay, tarih ve etiket bilgileriyle birlikte bir JSON dosyasına yazılır.
  1. Git’e commit et: Dosya, Git deposuna eklenir ve belirli bir açıklama ile commit edilir. Bu sayede tüm değişiklikler takip edilir ve yedeklenmiş olur.
  1. SQLite’ye indeksle: Olayın içeriği, trigram tokenizer kullanılan FTS5 tablosuna eklenir. Bu sayede hızlı ve etkili aramalar yapılabilir.

Bu mimari sayesinde, veritabanı sadece bir önbellek görevi görür. Verilerin asıl kaynağı Git deposu olduğu için, herhangi bir veri kaybı riski neredeyse sıfırdır. Aynı zamanda, indeksin bozulması ya da başka bir sorunla karşılaşılması durumunda, sadece bir komutla yeniden inşa etmek mümkün olur.

Sonuç: Basit bir ayarla gizli sorunu çözün

SQLite FTS5’in varsayılan ayarlarıyla Japonca, Çince ya da Korece gibi dillerde arama yaparken karşılaşılan sorun, ilk bakışta fark edilmesi zor bir durumdur. Ancak, tokenize='trigram' komutunu kullanarak bu sorunu sadece bir satırlık bir değişiklikle çözmek mümkün. Bu sayede, verilerinizdeki tüm dillerde etkili bir arama deneyimi yaşayabilirsiniz.

Verilerinizin boyutu ve kullanım senaryonuz göz önüne alındığında, trigram tokenizer’ın getirdiği indeks boyutundaki artış genellikle kabul edilebilir bir durumdur. Ayrıca, bu çözüm sayesinde veritabanı sadece bir önbellek görevi görürken, asıl veriler güvenilir bir şekilde Git’te saklanır. Gelecekte veri tabanınızla ilgili herhangi bir sorun yaşadığınızda, sadece indeksi yeniden inşa etmek yeterli olacaktır. Bu basit adımlarla, çok dilli bir arama sistemini kolayca kurabilir ve kullanabilirsiniz.

Verilerinizde Japonca, Çince ya da Korece içerik bulunuyor mu? O zaman bu basit ayarı hemen uygulamaya koymak için vakit kaybetmeyin.

Yapay zeka özeti

SQLite FTS5’in varsayılan ayarları Japonca, Çince ya da Korece metinlerde arama yaparken neden çalışmaz? Trigram tokenizer ile nasıl basit bir şekilde çözebilirsiniz? Detaylı açıklama ve uygulama örneği.

Yorumlar

00
YORUM BIRAK
ID #B7WLWW

0 / 1200 KARAKTER

İnsan doğrulaması

7 + 6 = ?

Editör onayı sonrası yayına girer

Moderasyon · Spam koruması aktif

Henüz onaylı yorum yok. İlk yorumu sen bırak.