brief: | i18n.site artık sunucusuz tam metin aramasını destekliyor.

Bu makale, IndexedDB tarafından oluşturulan ters çevrilmiş dizin, önek araması, kelime segmentasyonu optimizasyonu ve çoklu dil desteği de dahil olmak üzere saf ön uç tam metin arama teknolojisinin uygulanmasını tanıtmaktadır.

Mevcut çözümlerle karşılaştırıldığında, i18n.site'nin saf ön uç tam metin araması küçük boyutlu ve hızlıdır, belgeler ve bloglar gibi küçük ve orta ölçekli web siteleri için uygundur ve çevrimdışı olarak kullanılabilir.


Saf Ön Uç Tersine Çevrilmiş Tam Metin Araması

Sekans

Birkaç haftalık geliştirme sürecinin ardından i18n.site (tamamen statik markdown çok dilli çeviri & web sitesi oluşturma aracı) artık saf ön uç tam metin aramasını destekliyor.

Bu makale i18n.site arama efektini deneyimlemek için i18n.site saf ön uç tam metin aramasının teknik uygulamasını paylaşacaktır.

Açık kaynak kodunu arayın : Çekirdek / etkileşimli arayüzde arama yapın

Sunucusuz Tam Metin Arama Çözümlerine Genel Bakış

Belgeler/kişisel bloglar gibi küçük ve orta ölçekli tamamen statik web siteleri için, kendi kendine oluşturulmuş bir tam metin arama arka ucu oluşturmak çok ağırdır ve hizmet gerektirmeyen tam metin araması daha yaygın bir seçimdir.

Sunucusuz tam metin arama çözümleri iki geniş kategoriye ayrılır:

İlk olarak, benzer algolia.com Üçüncü taraf arama hizmeti sağlayıcıları, tam metin araması için ön uç bileşenler sağlar.

Bu tür hizmetler, arama hacmine göre ödeme yapılmasını gerektirir ve web sitesi uyumluluğu gibi sorunlar nedeniyle genellikle Çin ana karasındaki kullanıcılar tarafından kullanılamaz.

Çevrimdışı kullanılamaz, intranette kullanılamaz ve büyük sınırlamalara sahiptir. Bu makale çok fazla tartışmıyor.

İkincisi, saf ön uç tam metin aramasıdır.

Şu anda yaygın olarak kullanılan ön uç tam metin aramaları arasında lunrjs ve ElasticLunr.js ( lunrjs ikincil geliştirmeye dayalı) bulunmaktadır.

lunrjs Dizin oluşturmanın iki yolu vardır ve her ikisinin de kendi sorunları vardır.

  1. Önceden oluşturulmuş dizin dosyaları

    Dizin tüm belgelerden sözcükler içerdiğinden boyutu büyüktür. Bir belge eklendiğinde veya değiştirildiğinde yeni bir dizin dosyası yüklenmelidir. Kullanıcının bekleme süresini artıracak ve çok fazla bant genişliği tüketecektir.

  2. Belgeleri anında yükleyin ve dizinler oluşturun

    Dizin oluşturmak, hesaplama açısından yoğun bir iştir. Dizine her eriştiğinizde dizini yeniden oluşturmak, belirgin gecikmelere ve kötü kullanıcı deneyimine neden olur.


lunrjs ek olarak, : gibi başka tam metin arama çözümleri de vardır.

fusejs , aranacak dizeler arasındaki benzerliği hesaplayın.

Bu çözümün performansı son derece düşük ve tam metin araması için kullanılamaz (bkz Fuse.js Uzun sorgu 10 saniyeden fazla sürüyor, nasıl optimize edilir? ).

TinySearch , arama yapmak için Bloom filtresini kullanın, önek araması için kullanılamaz (örneğin, goo girin, good , google arayın) ve benzer otomatik tamamlama efekti elde edilemez.

Mevcut çözümlerin eksiklikleri nedeniyle i18n.site , aşağıdaki özelliklere sahip yeni bir saf ön uç tam metin arama çözümü geliştirdi :

  1. Çoklu dil aramayı destekler ve boyutu küçüktür. gzip paketlendikten sonra arama çekirdeğinin boyutu 6.9KB (karşılaştırma için lunrjs boyutu 25KB ).
  2. Daha az bellek kaplayan ve hızlı olan, indexedb dayalı ters çevrilmiş bir dizin oluşturun.
  3. Belgeler eklendiğinde/değiştirildiğinde, yalnızca eklenen veya değiştirilen belgeler yeniden indekslenerek hesaplama miktarı azaltılır.
  4. Önek aramayı destekler ve kullanıcı yazarken arama sonuçlarını gerçek zamanlı olarak görüntüleyebilir.
  5. Çevrimdışı kullanılabilir

Aşağıda i18n.site teknik uygulama detayı detaylı olarak tanıtılacaktır.

Çok Dilli Kelime Segmentasyonu

Kelime bölümlendirme, tarayıcının yerel kelime bölümlendirmesini Intl.Segmenter kullanır ve tüm genel tarayıcılar bu arayüzü destekler.

Word segmentation coffeescript kodu aşağıdaki gibidir

SEG = new Intl.Segmenter 0, granularity: "word"

seg = (txt) =>
  r = []
  for {segment} from SEG.segment(txt)
    for i from segment.split('.')
      i = i.trim()
      if i and !'| `'.includes(i) and !/\p{P}/u.test(i)
        r.push i
  r

export default seg

export segqy = (q) =>
  seg q.toLocaleLowerCase()

içinde: