brief: | i18n.site ຕອນນີ້ຮອງຮັບການຊອກຫາຂໍ້ຄວາມເຕັມແບບເຊີບເວີ.

ບົດຂຽນນີ້ແນະນໍາການປະຕິບັດເຕັກໂນໂລຢີການຊອກຫາຂໍ້ຄວາມເຕັມຫນ້າທາງຫນ້າອັນບໍລິສຸດ, ລວມທັງດັດສະນີ inverted ທີ່ສ້າງຂຶ້ນໂດຍ IndexedDB, ການຄົ້ນຫາຄໍານໍາຫນ້າ, ການເພີ່ມປະສິດທິພາບການແບ່ງສ່ວນຄໍາແລະການສະຫນັບສະຫນູນຫຼາຍພາສາ.

ເມື່ອປຽບທຽບກັບການແກ້ໄຂທີ່ມີຢູ່ແລ້ວ, ການຄົ້ນຫາຂໍ້ຄວາມເຕັມຫນ້າອັນບໍລິສຸດຂອງ i18n.site ແມ່ນມີຂະຫນາດນ້ອຍແລະໄວ, ເຫມາະສໍາລັບເວັບໄຊທ໌ຂະຫນາດນ້ອຍແລະຂະຫນາດກາງເຊັ່ນ: ເອກະສານແລະບລັອກ, ແລະມີຢູ່ໃນອອບໄລນ໌.


ການຊອກຫາຂໍ້ຄວາມເຕັມແບບປີ້ນດ້ານໜ້າອັນບໍລິສຸດ

ລຳດັບ

ຫຼັງຈາກການພັດທະ & ຫຼາຍໆ markdown ທິດ, i18n.site

ບົດຄວາມນີ້ຈະແບ່ງປັນການປະຕິບັດທາງດ້ານວິຊາການຂອງ i18n.site ການຊອກຫາຫນ້າທີ່ເຕັມທີ່ຫນ້າທີ່ເຕັມໄປຢ້ຽມຢາມ i18n.site

ລະ ຫັດ / ເປີດ :

ພາບລວມຂອງການແກ້ໄຂການຊອກຫາຂໍ້ຄວາມເຕັມແບບ serverless

ສໍາລັບເວັບໄຊທ໌ຂະຫນາດນ້ອຍແລະຂະຫນາດກາງແບບຄົງທີ່ຢ່າງດຽວເຊັ່ນເອກະສານ / ບລັອກສ່ວນບຸກຄົນ, ການສ້າງ backend ຄົ້ນຫາຂໍ້ຄວາມເຕັມທີ່ສ້າງດ້ວຍຕົນເອງແມ່ນຫນັກເກີນໄປ, ແລະການຄົ້ນຫາເຕັມຂໍ້ຄວາມທີ່ບໍ່ມີບໍລິການແມ່ນທາງເລືອກທົ່ວໄປກວ່າ.

ການແກ້ໄຂການຊອກຫາຂໍ້ຄວາມເຕັມແບບ Serverless ຕົກຢູ່ໃນສອງປະເພດກວ້າງ:

ທໍາອິດ, ຄ້າຍຄືກັນ algolia.com ຜູ້ໃຫ້ບໍລິການຄົ້ນຫາພາກສ່ວນທີສາມໃຫ້ອົງປະກອບດ້ານຫນ້າສໍາລັບການຄົ້ນຫາຂໍ້ຄວາມເຕັມ.

ການບໍລິການດັ່ງກ່າວຮຽກຮ້ອງໃຫ້ມີການຈ່າຍເງິນໂດຍອີງໃສ່ປະລິມານການຄົ້ນຫາ, ແລະມັກຈະບໍ່ມີໃຫ້ຜູ້ໃຊ້ໃນປະເທດຈີນແຜ່ນດິນໃຫຍ່ເນື່ອງຈາກບັນຫາເຊັ່ນການປະຕິບັດຕາມເວັບໄຊທ໌.

ມັນບໍ່ສາມາດຖືກນໍາໃຊ້ offline, ບໍ່ສາມາດນໍາໃຊ້ໃນອິນຕຣາເນັດ, ແລະມີຂໍ້ຈໍາກັດທີ່ຍິ່ງໃຫຍ່. ບົດຄວາມນີ້ບໍ່ໄດ້ສົນທະນາຫຼາຍ.

ອັນທີສອງແມ່ນການຊອກຫາຂໍ້ຄວາມເຕັມຫນ້າອັນບໍລິສຸດ.

ໃນປະຈຸບັນ, ການຄົ້ນຫາແບບເຕັມຕົວແບບທົ່ວໆໄປປະກອບມີ 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 , ແລະທຸກ browser ກະແສຫຼັກຮອງຮັບສ່ວນຕິດຕໍ່ນີ້.

ລະຫັດ segmentation 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 :

ຜ່ານໃນ array ຂອງເອກະສານ url ແລະສະບັບເລກທີ ver , ແລະຄົ້ນຫາວ່າເອກະສານມີຢູ່ໃນຕາຕະລາງ doc ຖ້າມັນບໍ່ມີ, ສ້າງດັດສະນີ inverted. ໃນເວລາດຽວກັນ, ເອົາດັດສະນີ inverted ສໍາລັບເອກະສານເຫຼົ່ານັ້ນທີ່ບໍ່ໄດ້ຜ່ານ.

ດ້ວຍວິທີນີ້, ການສ້າງດັດສະນີທີ່ເພີ່ມຂຶ້ນສາມາດບັນລຸໄດ້ແລະຈໍານວນການຄິດໄລ່ຫຼຸດລົງ.

ໃນການໂຕ້ຕອບທາງຫນ້າ, ແຖບຄວາມຄືບຫນ້າການໂຫຼດຂອງດັດຊະນີສາມາດສະແດງໄດ້ເພື່ອຫຼີກເວັ້ນການ lag ໃນເວລາໂຫຼດຄັ້ງທໍາອິດ, ເບິ່ງ "ແຖບຄວາມຄືບຫນ້າກັບ Animation, ອີງຕາມການດຽວ progress + Pure css ການປະຕິບັດ" English / ຈີນ .

IndexedDB ການຂຽນພ້ອມໆກັນສູງ

ໂຄງການດັ່ງກ່າວໄດ້ idb ໂດຍອີງໃສ່ການ encapsulation asynchronous ຂອງ IndexedDB

IndexedDB ອ່ານແລະຂຽນແມ່ນ asynchronous. ເມື່ອສ້າງດັດສະນີ, ເອກະສານຈະຖືກໂຫລດພ້ອມໆກັນເພື່ອສ້າງດັດສະນີ.

ເພື່ອຫຼີກເວັ້ນການສູນເສຍຂໍ້ມູນບາງສ່ວນທີ່ເກີດຈາກການຂຽນການແຂ່ງຂັນ, ທ່ານສາມາດອ້າງອີງໃສ່ລະຫັດ coffeescript ຂ້າງລຸ່ມນີ້ແລະເພີ່ມ ing cache ລະຫວ່າງການອ່ານແລະການຂຽນເພື່ອຂັດຂວາງການຂຽນທີ່ແຂ່ງຂັນ.

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 generator ເພື່ອປະຕິບັດການໂຫຼດຕາມຄວາມຕ້ອງການ, ແລະກັບຄືນ limit ຄັ້ງທີ່ມີຄໍາຖາມ.

ໃຫ້ສັງເກດວ່າແຕ່ລະຄັ້ງທີ່ທ່ານຄົ້ນຫາອີກເທື່ອຫນຶ່ງຫຼັງຈາກ yield , ທ່ານຈໍາເປັນຕ້ອງເປີດການເຮັດທຸລະກໍາການສອບຖາມຄືນໃຫມ່ຂອງ IndexedDB .

ນຳໜ້າການຄົ້ນຫາແບບສົດໆ

ເພື່ອສະແດງຜົນການຄົ້ນຫາໃນຂະນະທີ່ຜູ້ໃຊ້ກໍາລັງພິມ, ຕົວຢ່າງ, ເມື່ອ wor ຖືກປ້ອນ, ຄໍາທີ່ນໍາຫນ້າດ້ວຍ wor ເຊັ່ນ words ແລະ work ຈະຖືກສະແດງ.

kernel ຄົ້ນຫາຈະໃຊ້ຕາຕະລາງ prefix ສໍາລັບຄໍາສຸດທ້າຍຫຼັງຈາກການແບ່ງສ່ວນຄໍາເພື່ອຊອກຫາຄໍາທັງຫມົດທີ່ນໍາຫນ້າດ້ວຍມັນ, ແລະຄົ້ນຫາຕາມລໍາດັບ.

ຟັງຊັນຕ້ານການສັ່ນສະເທືອນ debounce ຍັງຖືກນໍາໃຊ້ໃນການໂຕ້ຕອບທາງຫນ້າ (ປະຕິບັດດັ່ງຕໍ່ໄປນີ້) ເພື່ອຫຼຸດຜ່ອນຄວາມຖີ່ຂອງການປ້ອນຂໍ້ມູນຂອງຜູ້ໃຊ້ທີ່ກະຕຸ້ນການຄົ້ນຫາແລະຫຼຸດຜ່ອນຈໍານວນການຄິດໄລ່.

export default (wait, func) => {
  var timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(func.bind(this, ...args), wait);
  };
}

ສາມາດໃຊ້ໄດ້ອອບລາຍ

ຕາຕະລາງດັດສະນີບໍ່ໄດ້ເກັບຮັກສາຂໍ້ຄວາມຕົ້ນສະບັບ, ມີພຽງແຕ່ຄໍາສັບຕ່າງໆ, ເຊິ່ງເຮັດໃຫ້ຈໍານວນການເກັບຮັກສາຫຼຸດລົງ.

ການເນັ້ນຜົນການຄົ້ນຫາຮຽກຮ້ອງໃຫ້ມີການໂຫຼດຂໍ້ຄວາມຕົ້ນສະບັບໃຫມ່, ແລະການຈັບຄູ່ service worker ສາມາດຫຼີກເວັ້ນການຮ້ອງຂໍເຄືອຂ່າຍຊ້ໍາກັນ.

ໃນເວລາດຽວກັນ, ເນື່ອງຈາກວ່າ service worker cache ບົດຄວາມທັງຫມົດ, ເມື່ອຜູ້ໃຊ້ດໍາເນີນການຄົ້ນຫາ, ເວັບໄຊທ໌ທັງຫມົດ, ລວມທັງການຄົ້ນຫາ, ແມ່ນມີຢູ່ໃນອອບໄລນ໌.

ສະແດງການເພີ່ມປະສິດທິພາບຂອງເອກະສານ MarkDown

i18n.site 's pure front-end search solution is optimized for MarkDown ເອກະສານ.

ເມື່ອສະແດງຜົນການຄົ້ນຫາ, ຊື່ບົດຈະຖືກສະແດງແລະບົດຈະຖືກນໍາທາງເມື່ອຄລິກ.

ສະຫຼຸບ

ການຊອກຫາຂໍ້ຄວາມເຕັມທີ່ປີ້ນກັບແມ່ນປະຕິບັດຢ່າງດຽວຢູ່ດ້ານຫນ້າ, ບໍ່ຈໍາເປັນຕ້ອງມີເຄື່ອງແມ່ຂ່າຍ. ມັນເຫມາະສົມຫຼາຍສໍາລັບເວັບໄຊທ໌ຂະຫນາດນ້ອຍແລະຂະຫນາດກາງເຊັ່ນເອກະສານແລະ blogs ສ່ວນບຸກຄົນ.

i18n.site ແຫຼ່ງເປີດທີ່ພັດທະນາຕົນເອງການຄົ້ນຫາແບບເຕັມຮູບແບບທີ່ບໍລິສຸດ, ຂະຫນາດນ້ອຍໃນຂະຫນາດແລະການຕອບສະຫນອງໄວ, ແກ້ໄຂຂໍ້ບົກຜ່ອງຂອງການຄົ້ນຫາແບບເຕັມຕົວຫນັງສືທາງຫນ້າທີ່ບໍລິສຸດໃນປະຈຸບັນແລະສະຫນອງປະສົບການຂອງຜູ້ໃຊ້ທີ່ດີກວ່າ.