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 хайлт хийхийн тулд Bloom шүүлтүүрийг ашигла, угтвар хайхад ашиглах боломжгүй (жишээ нь 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 Нээлттэй эхийн өөрөө хөгжүүлсэн цэвэр урд талын хайлт нь жижиг хэмжээтэй, хурдан хариу үйлдэл үзүүлэх нь одоогийн цэвэр урд талын бүрэн текст хайлтын дутагдлыг шийдэж, хэрэглэгчийн илүү сайн туршлагыг хангадаг.