brief: | i18n.site supporta avà a ricerca di testu pienu senza server.

Questu articulu introduce l'implementazione di a tecnulugia di ricerca di testu integrale di front-end pura, cumpresu l'indici invertitu custruitu da IndexedDB, ricerca di prefissi, ottimisazione di segmentazione di parole è supportu multi-lingua.

In cunfrontu cù e soluzioni esistenti, a ricerca di testu integrale di front-end pura di i18n.site hè chjuca è veloce, adatta per i siti web chjuchi è mediani cum'è documenti è blog, è hè dispunibule offline.


Ricerca Di Testu Integrale Invertita Pura Front-End

Sequenza

Dopu à parechje settimane di sviluppu, i18n.site (un strumentu puramente staticu markdown multilingualtranslation & per a creazione di siti web) supporta avà a ricerca di testu full-end pura.

Questu articulu hà da sparte l'implementazione tecnicu di i18n.site pura ricerca di testu in u front-end i18n.site per sperimentà l'effettu di ricerca.

Code open : Ricerca kernel / interfaccia interattiva

Una Panoramica Di E Soluzioni Di Ricerca Full-Text Senza Server

Per i siti web puramente statici chjuchi è mediani, cum'è documenti / blogs persunali, a custruzzione di un backend di ricerca full-text autocustruita hè troppu pesante, è a ricerca di testu cumpletu senza serviziu hè a scelta più cumuna.

Soluzioni di ricerca di testu pienu senza server sò in duie categorie larghe:

Prima, simili algolia.com i fornitori di servizii di ricerca di terze parti furniscenu cumpunenti front-end per a ricerca full-text.

Tali servizii necessitanu pagamentu basatu nantu à u voluminu di ricerca, è sò spessu indisponibili per l'utilizatori in Cina continentale per prublemi cum'è a conformità di u situ web.

Ùn pò micca esse usatu offline, ùn pò micca esse usatu in l'intranet, è hà grandi limitazioni. Questu articulu ùn parla micca assai.

U sicondu hè pura ricerca full-text front-end.

Attualmente, e ricerche di testu cumpletu puri cumuni includenu lunrjs è ElasticLunr.js (basatu nantu à u sviluppu secundariu lunrjs ).

lunrjs Ci hè duie manere di custruisce indici, è tutti dui anu i so prublemi.

  1. File d'indexu pre-custruiti

    Perchè l'indici cuntene parolle da tutti i documenti, hè grande in grandezza. Ogni volta chì un documentu hè aghjuntu o mudificatu, un novu schedariu d'indici deve esse caricatu. Aumenterà u tempu d'attesa di l'utilizatori è cunsuma assai larghezza di banda.

  2. Caricà i ducumenti è custruisce indici nantu à a mosca

    Custruì un indexu hè un compitu intensivu di calculu A ricustruisce l'indici ogni volta chì accede à ellu pruvucarà ritardi evidenti è una povera sperienza d'utilizatore.


In più di lunrjs , ci sò altre soluzioni di ricerca di testu pienu, cum'è :

fusejs , calculate a similarità trà e stringhe per circà.

A prestazione di sta suluzione hè estremamente povera è ùn pò micca esse usata per a ricerca full-text (vede Fuse.js A longa dumanda dura più di 10 seconde, cumu ottimisimu ? ).

TinySearch Aduprate u filtru Bloom per circà, ùn pò micca esse usatu per a ricerca di prefissu (per esempiu, entre goo , ricerca good , google ), è ùn pò micca ottene un effettu di cumpletu automaticu simili.

A causa di i difetti di e suluzioni esistenti, i18n.site hà sviluppatu una nova suluzione pura di ricerca di testu in front-end, chì hà e seguenti caratteristiche :

  1. Supporta a ricerca multilingua è hè chjuca in grandezza A dimensione di u kernel di ricerca dopu l'imballu gzip6.9KB (per paragunà, a dimensione di lunrjs25KB ).
  2. Custruisce un indice inversu basatu annantu à indexedb , chì occupa menu memoria è hè veloce.
  3. Quandu i ducumenti sò aghjuntu / mudificati, solu i documenti aghjunti o mudificati sò re-indexati, riducendu a quantità di calculi.
  4. Supporta a ricerca di prefissi, chì ponu visualizà risultati di ricerca in tempu reale mentre l'utilizatore scrive.
  5. Disponibile Offline

Sottu, i18n.site dettagli di implementazione tecnica seranu presentati in dettagliu.

Segmentazione Di Parole Multilingue

A segmentazione di e parolle usa a segmentazione di parola nativa di u navigatore Intl.Segmenter , è tutti i navigatori mainstream supportanu sta interfaccia.

U codice di segmentazione di a parolla coffeescript hè a siguenti

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()

in:

Custruzzione Di L'indice

5 tabelle di almacenamentu d'ughjettu sò state create in IndexedDB :

Passa in l'array di u documentu url è u numeru di versione ver , è cercate s'ellu esiste u documentu in a tavula doc S'ellu ùn esiste micca, crea un indice invertitu. À u listessu tempu, sguassate l'indici invertitu per quelli documenti chì ùn sò micca stati trasmessi.

In questu modu, l'indexazione incrementale pò esse ottenuta è a quantità di calculu hè ridutta.

In l'interazzione front-end, a barra di prugressu di carica di l'indici pò esse affissata per evità u ritardu quandu si carica per a prima volta Vede "Barra di prugressu cù Animazione, Basata nantu à una progress + implementazione css Pura" English / Chinese .

IndexedDB Alta Scrittura Simultanea

U prugettu hè idb basatu annantu à l'incapsulazione asincrona di IndexedDB

IndexedDB leghje è scrive sò asincroni. Quandu creanu un indice, i ducumenti seranu caricati simultaneamente per creà l'indici.

Per evitari a perdita di dati parziale causata da scrittura cumpetitiva, pudete riferite à u codice coffeescript quì sottu è aghjunghje una cache ing trà lettura è scrittura per intercepte i scritturi cuncurrenti.

pusher = =>
  ing = new Map()
  (table, id, val)=>
    id_set = ing.get(id)
    if id_set
      id_set.add val
      return

    id_set = new Set([val])
    ing.set id, id_set
    pre = await table.get(id)
    li = pre?.li or []

    loop
      to_add = [...id_set]
      li.push(...to_add)
      await table.put({id,li})
      for i from to_add
        id_set.delete i
      if not id_set.size
        ing.delete id
        break
    return

rindexPush = pusher()
prefixPush = pusher()

Precisione È Richiamata

A ricerca prima segmenterà e parole chjave inserite da l'utilizatore.

Assumimu chì ci sò N parolle dopu à a segmentazione di a parolla Quandu i risultati sò tornati, i risultati chì cuntenenu tutte e parole chjave seranu tornati prima, è dopu i risultati chì cuntenenu N-1 , N-2 ,..., 1 parole chjave.

I risultati di ricerca affissati prima assicuranu l'accuratezza di a dumanda, è i risultati caricati in seguitu (cliccate u buttone di carica più) assicuranu a freccia di ricurdà.

Carica Nantu À Dumanda

Per migliurà a veloce di risposta, a ricerca usa u generatore yield per implementà a carica nantu à a dumanda, è torna limit volta chì un risultatu hè dumandatu.

Nota chì ogni volta chì cercate di novu dopu à yield , avete bisognu di riapertura una transazzione di dumanda di IndexedDB .

Prefissu Di Ricerca in Tempu Reale

Per vede i risultati di ricerca mentre l'utilizatore scrive, per esempiu, quandu wor hè inseritu, e parolle prefissate cù wor cum'è words è work sò visualizate.

U kernel di ricerca utilizerà a tavola prefix per l'ultima parola dopu a segmentazione di a parolla per truvà tutte e parolle prefissate cun ella, è cercate in sequenza.

A funzione anti-shake debounce hè ancu aduprata in l'interazzione front-end (implementata cum'è seguita) per riduce a freccia di l'input di l'utilizatori chì attivanu e ricerche è riduce a quantità di calculu.

export default (wait, func) => {
  var timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(func.bind(this, ...args), wait);
  };
}

Disponibile Offline

A tavula d'indici ùn guarda micca u testu originale, solu e parolle, chì riduce a quantità di almacenamiento.

Evidenzià i risultati di ricerca richiede di ricaricà u testu uriginale, è l'abbinamentu di service worker pò evità e dumande di rete ripetute.

À u listessu tempu, perchè service worker cache tutti l'articuli, una volta chì l'utilizatore effettua una ricerca, tuttu u situ web, cumprese a ricerca, hè dispunibule offline.

Ottimisazione Di Visualizazione Di I Ducumenti MarkDown

A suluzione pura di ricerca front-end di i18n.site hè ottimizzata per MarkDown documenti.

Quandu si vede i risultati di ricerca, u nome di u capitulu serà affissatu è u capitulu serà navigatu quandu cliccate.

Riassume

A ricerca di testu integrale invertita implementata solu in u front-end, ùn hè micca necessariu un servitore. Hè assai adattatu per i siti web chjuchi è mediani cum'è documenti è blog persunali.

i18n.site A ricerca di front-end pura auto-sviluppata open source, chjuca in dimensione è risposta rapida, risolve i difetti di l'attuale ricerca di testu integrale di front-end pura è furnisce una sperienza d'utilizatore megliu.