brief: | i18n.site ახლა მხარს უჭერს სერვერის გარეშე სრული ტექსტის ძიებას.

ეს სტატია წარმოგიდგენთ სუფთა ფრონტ-ენდის სრული ტექსტის ძიების ტექნოლოგიის დანერგვას, IndexedDB-ის მიერ აგებული ინვერსიული ინდექსის ჩათვლით, პრეფიქსის ძიება, სიტყვების სეგმენტაციის ოპტიმიზაცია და მრავალენოვანი მხარდაჭერა.

არსებულ გადაწყვეტილებებთან შედარებით, i18n.site-ის სუფთა ფრონტალური სრული ტექსტის ძიება არის მცირე ზომის და სწრაფი, შესაფერისია მცირე და საშუალო ზომის ვებსაიტებისთვის, როგორიცაა დოკუმენტები და ბლოგები და ხელმისაწვდომია ხაზგარეშე.


Სუფთა Წინა Ნაწილის Ინვერსიული Სრული Ტექსტის Ძიება

Თანმიმდევრობა

რამდენიმე კვირიანი & შემდეგ markdown i18n.site

ეს სტატია გაიზიარებს i18n.site სუფთა ფრონტის სრული ტექსტის ძიების ტექნიკურ განხორციელებას i18n.site რათა განიცადოთ საძიებო ეფექტი.

კოდის ღია : ძიების ბირთვი / ინტერაქტიული ინტერფეისი

Სერვერის Გარეშე Სრული Ტექსტის Საძიებო Გადაწყვეტილებების Მიმოხილვა

მცირე და საშუალო ზომის წმინდა სტატიკური ვებსაიტებისთვის, როგორიცაა დოკუმენტები/პერსონალური ბლოგები, საკუთარი ხელით აშენებული სრული ტექსტის საძიებო გვერდის შექმნა ძალიან მძიმეა და სერვისის გარეშე სრული ტექსტის ძებნა ყველაზე გავრცელებული არჩევანია.

სერვერის გარეშე სრული ტექსტის საძიებო გადაწყვეტილებები იყოფა ორ ფართო კატეგორიად:

პირველი, algolia.com მესამე მხარის საძიებო სერვისის პროვაიდერები უზრუნველყოფენ წინა ნაწილის კომპონენტებს სრული ტექსტის ძიებისთვის.

ასეთი სერვისები საჭიროებს გადახდას ძიების მოცულობის მიხედვით და ხშირად მიუწვდომელია მომხმარებლებისთვის კონტინენტზე ჩინეთში ისეთი საკითხების გამო, როგორიცაა ვებსაიტების შესაბამისობა.

მისი გამოყენება შეუძლებელია ოფლაინში, არ შეიძლება გამოყენებულ იქნას ინტრანეტში და აქვს დიდი შეზღუდვები. ეს სტატია ბევრს არ განიხილავს.

მეორე არის სუფთა ფრონტის სრული ტექსტის ძებნა.

ამჟამად, ElasticLunr.js სუფთა ფრონტის სრული lunrjs ძიება მოიცავს 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()

in:

Ინდექსის Შენობა

ობიექტის შენახვის 5 ცხრილი შეიქმნა IndexedDB -ში :

ჩაატარეთ დოკუმენტის url და ვერსიის ნომერი ver მასივი და მოძებნეთ დოკუმენტი არსებობს თუ არა ცხრილში doc თუ ის არ არსებობს, შექმენით ინვერსიული ინდექსი. ამავდროულად, ამოიღეთ ინვერსიული ინდექსი იმ დოკუმენტებისთვის, რომლებიც არ იყო გადაცემული.

ამ გზით შეიძლება მიღწეული იქნას ინკრემენტული ინდექსირება და მცირდება გაანგარიშების რაოდენობა.

ფრონტალური ურთიერთქმედებისას, ინდექსის ჩატვირთვის პროგრესის ზოლი შეიძლება გამოჩნდეს, რათა თავიდან იქნას აცილებული ჩამორჩენა პირველად ჩატვირთვისას იხილეთ "პროგრესის ზოლი ანიმაციით, ერთიან progress + Pure css Implementation" ინგლისური / ჩინური .

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 ცხრილს ბოლო სიტყვისთვის სიტყვის სეგმენტაციის შემდეგ, რათა იპოვოს მასთან პრეფიქსის მქონე ყველა სიტყვა და მოიძიოს თანმიმდევრობით.

შერყევის საწინააღმდეგო ფუნქცია 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 ღია წყაროს თვითგანვითარებული სუფთა ფრონტ-ენდის ძიება, მცირე ზომის და სწრაფი რეაგირება, აგვარებს მიმდინარე სუფთა ფრონტ-ენდის სრული ტექსტის ძიების ხარვეზებს და უზრუნველყოფს მომხმარებლის უკეთეს გამოცდილებას.