brief: | и18н.сите сада подржава претрагу пуног текста без сервера.

Овај чланак уводи имплементацију чисте фронт-енд технологије претраживања пуног текста, укључујући обрнути индекс који је направио ИндекедДБ, претрагу префикса, оптимизацију сегментације речи и подршку за више језика.

У поређењу са постојећим решењима, чиста фронт-енд претрага целог текста и18н.сите је мале величине и брза, погодна за мале и средње веб локације као што су документи и блогови, и доступна је ван мреже.


Чиста Фронт-Енд Инвертована Претрага Целог Текста

Секвенца

Након неколико седмица развоја, 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()

у:

Изградња Индекса

5 табела за складиштење објеката креирано је у IndexedDB :

Проследите низ документа url и верзије број ver и потражите да ли документ постоји у табели doc Ако не постоји, креирајте обрнути индекс. Истовремено, уклоните обрнути индекс за оне документе који нису прослеђени.

На овај начин се може постићи инкрементално индексирање и смањити количина обрачуна.

У фронт-енд интеракцији, трака тока учитавања индекса може да се прикаже да би се избегло кашњење при првом учитавању Погледајте „Трака напретка са анимацијом, заснована на једној progress + Чиста css имплементација“ енглески / кинески .

ИндекедДБ Високо Истовремено Писање

Пројекат је idb на основу асинхроне енкапсулације 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 , приказују се речи са префиксом wor као што су words и work .

Кернел за претрагу ће користити табелу 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 Саморазвијена чиста фронт-енд претрага отвореног кода, мале величине и брзог одзива, решава недостатке тренутне чисте фронт-енд претраге целог текста и пружа боље корисничко искуство.