brief: | i18n.site енді серверсіз толық мәтінді іздеуді қолдайды.
Бұл мақала IndexedDB құрастырған инверттелген индексті, префиксті іздеуді, сөзді сегменттеуді оңтайландыруды және көп тілді қолдауды қоса, таза толық мәтінді іздеу технологиясын енгізуді ұсынады.
Қолданыстағы шешімдермен салыстырғанда, i18n.site сайтының таза толық мәтінді іздеу көлемі шағын және жылдам, құжаттар мен блогтар сияқты шағын және орта өлшемді веб-сайттар үшін қолайлы және офлайн режимінде қол жетімді.
Бірнеше апталық әзірлеуден кейін i18n.site (таза статикалық markdown көптілді аударма & веб-сайт құру құралы) енді таза толық мәтінді іздеуді қолдайды.
Бұл мақалада іздеу эффектісін i18n.site үшін i18n.site
таза толық мәтінді іздеуді бөліседі.
Ашық : кодты іздеу ядросы / интерактивті интерфейс
Құжаттар/жеке блогтар сияқты шағын және орта өлшемді таза статикалық веб-сайттар үшін өздігінен құрастырылған толық мәтінді іздеу серверін құру тым ауыр және қызметсіз толық мәтінді іздеу кең таралған таңдау болып табылады.
Серверсіз толық мәтінді іздеу шешімдері екі кең санатқа бөлінеді:
Біріншіден, algolia.com үшінші тарап іздеу қызметінің провайдерлері толық мәтінді іздеуге арналған алдыңғы компоненттерді қамтамасыз етеді.
Мұндай қызметтер іздеу көлеміне негізделген төлемді талап етеді және веб-сайттың сәйкестігі сияқты мәселелерге байланысты материктік Қытайдағы пайдаланушылар үшін жиі қолжетімсіз.
Оны желіден тыс пайдалануға болмайды, интранетте пайдалануға болмайды және үлкен шектеулер бар. Бұл мақалада көп айтылмайды.
Екіншісі - таза толық мәтінді іздеу.
Қазіргі уақытта жалпы таза толық мәтінді іздеуге lunrjs және ElasticLunr.js ( lunrjs
қосымша әзірлеу негізінде) кіреді.
lunrjs
Индекстерді құрудың екі жолы бар және екеуінің де өз мәселелері бар.
Алдын ала жасалған индекстік файлдар
Индекс барлық құжаттардағы сөздерді қамтитындықтан, оның көлемі үлкен. Құжат қосылғанда немесе өзгертілгенде, жаңа индекс файлы жүктелуі керек. Бұл пайдаланушының күту уақытын арттырады және өткізу қабілеттілігін көп тұтынады.
Құжаттарды жүктеңіз және индекстерді жылдам жасаңыз
Индекс құру – есептеуді қажет ететін тапсырма, оған қол жеткізген сайын оны қайта құру анық кешігулер мен нашар пайдаланушы тәжірибесін тудырады.
lunrjs
-ден басқа толық мәтінді іздеу шешімдері бар, мысалы :
fusejs іздеу үшін жолдар арасындағы ұқсастықты есептеңіз.
Бұл шешімнің өнімділігі өте нашар және оны толық мәтінді іздеу үшін пайдалану мүмкін емес (қараңыз Fuse.js Ұзақ сұрауға 10 секундтан астам уақыт кетеді, оны қалай оңтайландыру керек? ).
TinySearch , іздеу үшін Блум сүзгісін пайдаланыңыз, префиксті іздеу үшін пайдаланылмайды (мысалы, goo
, іздеу good
, google
енгізіңіз) және ұқсас автоматты аяқтау әсеріне қол жеткізу мүмкін емес.
Қолданыстағы шешімдердің кемшіліктеріне байланысты i18n.site
келесі сипаттамаларға ие жаңа таза толық мәтінді іздеу шешімін әзірледі :
gzip
орамынан кейінгі іздеу ядросының өлшемі 6.9KB
(салыстыру үшін lunrjs
өлшемі 25KB
)indexedb
негізінде инверттелген индексті құрастырыңыз, ол жадты азырақ алады және жылдам.Төменде i18n.site
техникалық іске асыру мәліметтері егжей-тегжейлі енгізіледі.
Сөзді сегменттеу браузердің жергілікті сөз сегментациясын Intl.Segmenter
пайдаланады және барлық негізгі браузерлер осы интерфейсті қолдайды.
Сөзді сегменттеу coffeescript
коды келесідей
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()
ішінде:
/\p{P}/
- ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _
белгілеріне сәйкес келетін тұрақты өрнек { | } ~. .</p><ul><li>
split('.')себебі,
Firefoxшолғыш сөзін сегменттеу
. ` сегменттемейді.
IndexedDB
-де 5 объект сақтау кестесі жасалды :
word
: id -doc
: id - Құжат url - Құжат нұсқасының нөміріdocWord
: id - id құжаттың массивіprefix
- префикстің : idrindex
: Word id - Document id : Жол нөмірлерінің массивіurl
құжатының массивіне және ver
нұсқаға өтіп, құжаттың doc
кестеде бар-жоғын іздеңіз. Егер ол жоқ болса, инверттелген индексті жасаңыз. Сонымен қатар, қабылданбаған құжаттар үшін инверттелген индексті алып тастаңыз.
Осылайша, қосымша индекстеуге қол жеткізуге болады және есептеу көлемі азаяды.
Фронттың өзара әрекеттесуінде, бірінші рет жүктеген кезде progress + css / индекстің жүктелу барысы жолағын көрсетуге болады.
Жоба асинхронды инкапсуляция негізінде idb IndexedDB
IndexedDB оқу және жазу асинхронды. Индексті жасау кезінде құжаттар индексті жасау үшін бір мезгілде жүктеледі.
Бәсекелес жазудан туындаған деректердің ішінара жоғалуын болдырмау үшін төмендегі coffeescript
кодын қараңыз және бәсекелес жазуларды тоқтату үшін оқу мен жазу арасында ing
кэш қосуға болады.
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()
Іздеу алдымен пайдаланушы енгізген кілт сөздерді сегменттейді.
Сөзді сегменттеуден кейін N
сөз бар деп есептейік. Нәтижелерді қайтарған кезде, алдымен барлық кілт сөздерді қамтитын нәтижелер қайтарылады, содан кейін N-1
, N-2
,..., 1
кілт сөздері бар нәтижелер қайтарылады.
Көрсетілген іздеу нәтижелері алдымен сұраудың дәлдігін қамтамасыз етеді, ал кейін жүктелген нәтижелер (қосымша жүктеу түймесін басыңыз) шақыру жылдамдығын қамтамасыз етеді.
Жауап беру жылдамдығын жақсарту үшін іздеу сұраныс бойынша жүктеуді жүзеге асыру үшін yield
генераторын пайдаланады және нәтиже сұралған limit
қайтарады.
yield
кейін қайта іздеген сайын IndexedDB
сұрау транзакциясын қайта ашу қажет екенін ескеріңіз.
Пайдаланушы теріп жатқанда іздеу нәтижелерін көрсету үшін, мысалы, wor
енгізілгенде, words
және work
сияқты wor
префиксі бар сөздер көрсетіледі.
Іздеу ядросы сөзді сегменттеуден кейінгі соңғы сөз үшін prefix
кестесін пайдаланып, префиксті барлық сөздерді тауып, ретімен іздейді.
Шайқауға қарсы debounce
функциясы сонымен қатар пайдаланушы енгізуін іске қосатын іздеулер жиілігін азайту және есептеу көлемін азайту үшін алдыңғы қатардағы өзара әрекеттесуде қолданылады (төмендегідей жүзеге асырылады).
export default (wait, func) => {
var timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(func.bind(this, ...args), wait);
};
}
Индекс кестесі бастапқы мәтінді сақтамайды, тек сөздерді сақтайды, бұл сақтау көлемін азайтады.
Іздеу нәтижелерін бөлектеу бастапқы мәтінді қайта жүктеуді талап етеді және service worker
ге сәйкес келу қайталанатын желі сұрауларын болдырмайды.
Сонымен қатар, service worker
барлық мақалаларды кэштейді, өйткені пайдаланушы іздеуді орындағаннан кейін бүкіл веб-сайт, соның ішінде іздеу офлайн режимінде қолжетімді болады.
i18n.site
ның таза фронтальды іздеу шешімі MarkDown
құжат үшін оңтайландырылған.
Іздеу нәтижелерін көрсету кезінде тарау атауы көрсетіледі және басқан кезде тарау шарланады.
Төңкерілген толық мәтінді іздеу тек алдыңғы жағында жүзеге асырылады, сервер қажет емес. Құжаттар мен жеке блогтар сияқты шағын және орта веб-сайттар үшін өте қолайлы.
i18n.site
Ашық бастапқы кодты өздігінен әзірлеген таза фронтальды іздеу, өлшемі шағын және жылдам жауап береді, қазіргі таза толық мәтінді іздеудің кемшіліктерін шешеді және жақсырақ пайдаланушы тәжірибесін қамтамасыз етеді.