brief: | i18n.site ondersteun nou bedienerlose voltekssoektog.
Hierdie artikel stel die implementering van suiwer front-end volteks soektegnologie bekend, insluitend omgekeerde indeks gebou deur IndexedDB, voorvoegselsoektog, woordsegmenteringsoptimalisering en multi-taalondersteuning.
In vergelyking met bestaande oplossings, is i18n.site se suiwer voorkant-voltekssoektog klein en vinnig, geskik vir klein en mediumgrootte webwerwe soos dokumente en blogs, en is vanlyn beskikbaar.
Na 'n paar weke van ontwikkeling, ondersteun i18n.site ('n suiwer statiese markdown veeltalige vertaling & webwerfbou-instrument) nou suiwer front-end volteks soektog.
Hierdie artikel sal die tegniese implementering van i18n.site
suiwer voorkant-voltekssoektog deel i18n.site die soekeffek te ervaar.
Kode : Soek kern / interaktiewe koppelvlak
Vir klein en mediumgrootte suiwer statiese webwerwe soos dokumente/persoonlike blogs, is dit te swaar om 'n selfgeboude voltekssoektog-agtergrond te bou, en diensvrye voltekssoektog is die meer algemene keuse.
Bedienerlose volteks soekoplossings val in twee breë kategorieë:
Eerstens, algolia.com derdeparty-soekdiensverskaffers verskaf front-end-komponente vir voltekssoektog.
Sulke dienste vereis betaling gebaseer op soekvolume, en is dikwels nie beskikbaar vir gebruikers op die vasteland van China nie weens kwessies soos webwerf-nakoming.
Dit kan nie vanlyn gebruik word nie, kan nie op die intranet gebruik word nie, en het groot beperkings. Hierdie artikel bespreek nie veel nie.
Die tweede is suiwer front-end volteks soektog.
Tans sluit algemene suiwer voorkant-voltekssoektogte in lunrjs en ElasticLunr.js (gebaseer op lunrjs
sekondêre ontwikkeling).
lunrjs
Daar is twee maniere om indekse te bou, en albei het hul eie probleme.
Voorafgeboude indekslêers
Omdat die indeks woorde uit alle dokumente bevat, is dit groot in grootte. Wanneer 'n dokument bygevoeg of gewysig word, moet 'n nuwe indekslêer gelaai word. Dit sal die gebruiker se wagtyd verhoog en baie bandwydte verbruik.
Laai dokumente en bou indekse op die vlieg
Die bou van 'n indeks is 'n berekeningsintensiewe taak Om die indeks te herbou elke keer as jy dit ingaan, sal duidelike vertragings en swak gebruikerservaring veroorsaak.
Benewens lunrjs
, is daar 'n paar ander volteks soekoplossings, soos :
fusejs bereken die ooreenkoms tussen stringe om te soek.
Die werkverrigting van hierdie oplossing is uiters swak en kan nie vir voltekssoektog gebruik word nie (sien Fuse.js Lang navraag neem meer as 10 sekondes, hoe om dit te optimaliseer? ).
TinySearch , gebruik Bloom-filter om te soek, kan nie vir voorvoegselsoektog gebruik word nie (tik byvoorbeeld goo
, soek good
, google
), en kan nie soortgelyke outomatiese voltooiingseffek bereik nie.
As gevolg van die tekortkominge van die bestaande oplossings, het i18n.site
'n nuwe suiwer front-end volteks soekoplossing ontwikkel, wat die volgende kenmerke het :
gzip
is 6.9KB
(ter vergelyking, die grootte van lunrjs
is 25KB
).indexedb
, wat minder geheue opneem en vinnig is.Hieronder sal i18n.site
tegniese implementeringbesonderhede in detail bekendgestel word.
Woordsegmentering gebruik die blaaier se inheemse woordsegmentering Intl.Segmenter
, en alle hoofstroomblaaiers ondersteun hierdie koppelvlak.
Die woordsegmentasie coffeescript
kode is soos volg
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:
/\p{P}/
is 'n gereelde uitdrukking wat ooreenstem met leestekens. Spesifieke bypassende simbole sluit in: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _
{ | } ~. .</p><ul><li>
split('.')is omdat
Firefoxblaaierwoordsegmentering nie
. ` segmenteer nie.
5 voorwerpbergingstafels is in IndexedDB
geskep :
word
: id -doc
: id - Dokument url - DokumentweergawenommerdocWord
: Skikking van dokument id - woord idprefix
: Skikking van voorvoegsel - woord idrindex
: Word id - Dokument id : Skikking van lynnommersSlaag die skikking van dokument url
en weergawe nommer ver
in, en soek of die dokument bestaan in tabel doc
As dit nie bestaan nie, skep 'n omgekeerde indeks. Verwyder terselfdertyd die omgekeerde indeks vir daardie dokumente wat nie ingedien is nie.
Op hierdie manier kan inkrementele indeksering bereik word en die hoeveelheid berekening word verminder.
In die voorkant-interaksie kan die laai -vorderingsbalk css die indeks vertoon word / die progress + te vermy wanneer dit vir die eerste keer gelaai word.
Die projek is idb gebaseer op die asinchroniese inkapseling van IndexedDB
IndexedDB lees en skryf is asynchronies. Wanneer 'n indeks geskep word, sal dokumente gelyktydig gelaai word om die indeks te skep.
Om gedeeltelike dataverlies wat deur mededingende skryfwerk veroorsaak word, te vermy, kan jy na die coffeescript
kode hieronder verwys en 'n ing
kas tussen lees en skryf byvoeg om mededingende skryfwerk te onderskep.
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()
Die soektog sal eers die sleutelwoorde segmenteer wat deur die gebruiker ingevoer is.
Aanvaar dat daar N
woorde na die woordsegmentering is Wanneer resultate teruggestuur word, sal resultate wat alle sleutelwoorde bevat, eerste teruggestuur word, en dan sal resultate wat N-1
, N-2
,..., 1
sleutelwoorde bevat.
Die soekresultate wat eers vertoon word, verseker die akkuraatheid van die navraag, en die resultate wat daarna gelaai word (klik op die laai meer-knoppie) verseker die herroeptempo.
Om die reaksiespoed te verbeter, gebruik die soektog die yield
generator om laai op aanvraag te implementeer, en keer terug limit
keer as 'n resultaat navraag gedoen word.
Let daarop dat elke keer as jy weer na yield
soek, jy 'n navraagtransaksie van IndexedDB
moet heropen.
Om soekresultate te vertoon terwyl die gebruiker tik, byvoorbeeld, wanneer wor
ingevoer word, word woorde wat met wor
voorvoeg, soos words
en work
vertoon.
Die soekkern sal die prefix
tabel vir die laaste woord na woordsegmentering gebruik om alle woorde wat daarmee voorafgaan te vind, en in volgorde te soek.
Anti-skud funksie debounce
word ook gebruik in voorkant-interaksie (soos geïmplementeer) om die frekwensie van gebruikerinvoer wat soektogte veroorsaak, te verminder en die hoeveelheid berekening te verminder.
export default (wait, func) => {
var timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(func.bind(this, ...args), wait);
};
}
Die indekstabel stoor nie die oorspronklike teks nie, slegs die woorde, wat die hoeveelheid berging verminder.
Om soekresultate uit te lig, vereis dat die oorspronklike teks herlaai word, en passing service worker
kan herhaalde netwerkversoeke vermy.
Terselfdertyd, omdat service worker
alle artikels kas, sodra die gebruiker 'n soektog uitvoer, is die hele webwerf, insluitend die soektog, vanlyn beskikbaar.
i18n.site
se suiwer front-end soek oplossing is geoptimaliseer vir MarkDown
dokumente.
Wanneer soekresultate vertoon word, sal die hoofstuknaam vertoon word en die hoofstuk sal navigeer word wanneer daarop geklik word.
Omgekeerde voltekssoektog wat suiwer aan die voorkant geïmplementeer is, geen bediener benodig nie. Dit is baie geskik vir klein en medium-grootte webwerwe soos dokumente en persoonlike blogs.
i18n.site
Oopbron self-ontwikkelde suiwer front-end soektog, klein in grootte en vinnige reaksie, los die tekortkominge van die huidige suiwer front-end volteks soektog op en bied 'n beter gebruikerservaring.