brief: | i18n.site енді серверсіз толық мәтінді іздеуді қолдайды.

Бұл мақала IndexedDB құрастырған инверттелген индексті, префиксті іздеуді, сөзді сегменттеуді оңтайландыруды және көп тілді қолдауды қоса, таза толық мәтінді іздеу технологиясын енгізуді ұсынады.

Қолданыстағы шешімдермен салыстырғанда, i18n.site сайтының таза толық мәтінді іздеу көлемі шағын және жылдам, құжаттар мен блогтар сияқты шағын және орта өлшемді веб-сайттар үшін қолайлы және офлайн режимінде қол жетімді.


Таза Алдыңғы Жағындағы Инверттелген Толық Мәтінді Іздеу

Реттілік

Бірнеше апталық әзірлеуден кейін i18n.site (таза статикалық markdown көптілді аударма & веб-сайт құру құралы) енді таза толық мәтінді іздеуді қолдайды.

Бұл мақалада іздеу эффектісін i18n.site үшін i18n.site таза толық мәтінді іздеуді бөліседі.

Ашық : кодты іздеу ядросы / интерактивті интерфейс

Серверсіз Толық Мәтінді Іздеу Шешімдеріне Шолу

Құжаттар/жеке блогтар сияқты шағын және орта өлшемді таза статикалық веб-сайттар үшін өздігінен құрастырылған толық мәтінді іздеу серверін құру тым ауыр және қызметсіз толық мәтінді іздеу кең таралған таңдау болып табылады.

Серверсіз толық мәтінді іздеу шешімдері екі кең санатқа бөлінеді:

Біріншіден, algolia.com үшінші тарап іздеу қызметінің провайдерлері толық мәтінді іздеуге арналған алдыңғы компоненттерді қамтамасыз етеді.

Мұндай қызметтер іздеу көлеміне негізделген төлемді талап етеді және веб-сайттың сәйкестігі сияқты мәселелерге байланысты материктік Қытайдағы пайдаланушылар үшін жиі қолжетімсіз.

Оны желіден тыс пайдалануға болмайды, интранетте пайдалануға болмайды және үлкен шектеулер бар. Бұл мақалада көп айтылмайды.

Екіншісі - таза толық мәтінді іздеу.

Қазіргі уақытта жалпы таза толық мәтінді іздеуге lunrjs және ElasticLunr.js ( lunrjs қосымша әзірлеу негізінде) кіреді.

lunrjs Индекстерді құрудың екі жолы бар және екеуінің де өз мәселелері бар.

  1. Алдын ала жасалған индекстік файлдар

    Индекс барлық құжаттардағы сөздерді қамтитындықтан, оның көлемі үлкен. Құжат қосылғанда немесе өзгертілгенде, жаңа индекс файлы жүктелуі керек. Бұл пайдаланушының күту уақытын арттырады және өткізу қабілеттілігін көп тұтынады.

  2. Құжаттарды жүктеңіз және индекстерді жылдам жасаңыз

    Индекс құру – есептеуді қажет ететін тапсырма, оған қол жеткізген сайын оны қайта құру анық кешігулер мен нашар пайдаланушы тәжірибесін тудырады.


lunrjs -ден басқа толық мәтінді іздеу шешімдері бар, мысалы :

fusejs іздеу үшін жолдар арасындағы ұқсастықты есептеңіз.

Бұл шешімнің өнімділігі өте нашар және оны толық мәтінді іздеу үшін пайдалану мүмкін емес (қараңыз Fuse.js Ұзақ сұрауға 10 секундтан астам уақыт кетеді, оны қалай оңтайландыру керек? ).

TinySearch , іздеу үшін Блум сүзгісін пайдаланыңыз, префиксті іздеу үшін пайдаланылмайды (мысалы, goo , іздеу good , google енгізіңіз) және ұқсас автоматты аяқтау әсеріне қол жеткізу мүмкін емес.

Қолданыстағы шешімдердің кемшіліктеріне байланысты i18n.site келесі сипаттамаларға ие жаңа таза толық мәтінді іздеу шешімін әзірледі :

  1. Көптілді іздеуді қолдайды және өлшемі шағын gzip орамынан кейінгі іздеу ядросының өлшемі 6.9KB (салыстыру үшін lunrjs өлшемі 25KB )
  2. indexedb негізінде инверттелген индексті құрастырыңыз, ол жадты азырақ алады және жылдам.
  3. Құжаттар қосылған/өзгертілген кезде тек қосылған немесе өзгертілген құжаттар ғана қайта индекстеледі, бұл есептеулер көлемін азайтады.
  4. Пайдаланушы теріп жатқанда нақты уақытта іздеу нәтижелерін көрсете алатын префиксті іздеуді қолдайды.
  5. Офлайн Режимінде Қол Жетімді

Төменде 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()

ішінде:

Индекс Құру

IndexedDB -де 5 объект сақтау кестесі жасалды :

url құжатының массивіне және ver нұсқаға өтіп, құжаттың doc кестеде бар-жоғын іздеңіз. Егер ол жоқ болса, инверттелген индексті жасаңыз. Сонымен қатар, қабылданбаған құжаттар үшін инверттелген индексті алып тастаңыз.

Осылайша, қосымша индекстеуге қол жеткізуге болады және есептеу көлемі азаяды.

Фронттың өзара әрекеттесуінде, бірінші рет жүктеген кезде progress + css / индекстің жүктелу барысы жолағын көрсетуге болады.

IndexedDB Жоғары Бір Мезгілде Жазу

Жоба асинхронды инкапсуляция негізінде 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 барлық мақалаларды кэштейді, өйткені пайдаланушы іздеуді орындағаннан кейін бүкіл веб-сайт, соның ішінде іздеу офлайн режимінде қолжетімді болады.

MarkDown Құжаттарын Оңтайландыруды Көрсету

i18n.site ның таза фронтальды іздеу шешімі MarkDown құжат үшін оңтайландырылған.

Іздеу нәтижелерін көрсету кезінде тарау атауы көрсетіледі және басқан кезде тарау шарланады.

Қорытындылау

Төңкерілген толық мәтінді іздеу тек алдыңғы жағында жүзеге асырылады, сервер қажет емес. Құжаттар мен жеке блогтар сияқты шағын және орта веб-сайттар үшін өте қолайлы.

i18n.site Ашық бастапқы кодты өздігінен әзірлеген таза фронтальды іздеу, өлшемі шағын және жылдам жауап береді, қазіргі таза толық мәтінді іздеудің кемшіліктерін шешеді және жақсырақ пайдаланушы тәжірибесін қамтамасыз етеді.