brief: | i18n.site цяпер падтрымлівае бессерверны паўнатэкставы пошук.

Гэты артыкул знаёміць з рэалізацыяй чыстай інтэрфейснай тэхналогіі паўнатэкставага пошуку, уключаючы інвертаваны індэкс, створаны IndexedDB, пошук па прэфіксах, аптымізацыю сегментацыі слоў і падтрымку некалькіх моў.

У параўнанні з існуючымі рашэннямі, чысты інтэрфейсны паўнатэкставы пошук i18n.site мае малы памер і хуткасць, падыходзіць для малых і сярэдніх вэб-сайтаў, такіх як дакументы і блогі, і даступны ў аўтаномным рэжыме.


Чысты Інтэрфейсны Перавернуты Паўнатэкставы Пошук

Паслядоўнасць

Пасля некалькіх тыдняў распрацоўкі i18n.site (чыста статычны markdown multilingualtranslation & інструмент для стварэння вэб-сайтаў) цяпер падтрымлівае чысты інтэрфейсны паўнатэкставы пошук.

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 Калі ён не існуе, стварыце інвертаваны індэкс. У той жа час выдаліце інвертаваны індэкс для тых дакументаў, якія не былі перададзены.

Такім чынам можна дамагчыся паступовай індэксацыі і паменшыць аб'ём разліку.

У франтальным узаемадзеянні можа / адлюстравана панэль ходу загрузкі індэкса, css пазбегнуць затрымкі пры загрузцы ў першы progress + . Гл .

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 , адлюстроўваюцца словы з прэфіксам wor , напрыклад words і work .

Ядро пошуку будзе выкарыстоўваць табліцу prefix для апошняга слова пасля сегментацыі слова, каб знайсці ўсе словы з прэфіксам і шукаць паслядоўна.

Функцыя Anti-shake 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 Аўтаматычны пошук з адкрытым зыходным кодам, невялікі па памеры і хуткі адказ, ліквідуе недахопы цяперашняга поўнатэкставага пошуку і забяспечвае лепшы карыстацкі досвед.