brief: | i18n.site ახლა მხარს უჭერს სერვერის გარეშე სრული ტექსტის ძიებას.
ეს სტატია წარმოგიდგენთ სუფთა ფრონტ-ენდის სრული ტექსტის ძიების ტექნოლოგიის დანერგვას, IndexedDB-ის მიერ აგებული ინვერსიული ინდექსის ჩათვლით, პრეფიქსის ძიება, სიტყვების სეგმენტაციის ოპტიმიზაცია და მრავალენოვანი მხარდაჭერა.
არსებულ გადაწყვეტილებებთან შედარებით, i18n.site-ის სუფთა ფრონტალური სრული ტექსტის ძიება არის მცირე ზომის და სწრაფი, შესაფერისია მცირე და საშუალო ზომის ვებსაიტებისთვის, როგორიცაა დოკუმენტები და ბლოგები და ხელმისაწვდომია ხაზგარეშე.
რამდენიმე კვირიანი & შემდეგ markdown i18n.site
ეს სტატია გაიზიარებს i18n.site
სუფთა ფრონტის სრული ტექსტის ძიების ტექნიკურ განხორციელებას i18n.site რათა განიცადოთ საძიებო ეფექტი.
კოდის ღია : ძიების ბირთვი / ინტერაქტიული ინტერფეისი
მცირე და საშუალო ზომის წმინდა სტატიკური ვებსაიტებისთვის, როგორიცაა დოკუმენტები/პერსონალური ბლოგები, საკუთარი ხელით აშენებული სრული ტექსტის საძიებო გვერდის შექმნა ძალიან მძიმეა და სერვისის გარეშე სრული ტექსტის ძებნა ყველაზე გავრცელებული არჩევანია.
სერვერის გარეშე სრული ტექსტის საძიებო გადაწყვეტილებები იყოფა ორ ფართო კატეგორიად:
პირველი, algolia.com მესამე მხარის საძიებო სერვისის პროვაიდერები უზრუნველყოფენ წინა ნაწილის კომპონენტებს სრული ტექსტის ძიებისთვის.
ასეთი სერვისები საჭიროებს გადახდას ძიების მოცულობის მიხედვით და ხშირად მიუწვდომელია მომხმარებლებისთვის კონტინენტზე ჩინეთში ისეთი საკითხების გამო, როგორიცაა ვებსაიტების შესაბამისობა.
მისი გამოყენება შეუძლებელია ოფლაინში, არ შეიძლება გამოყენებულ იქნას ინტრანეტში და აქვს დიდი შეზღუდვები. ეს სტატია ბევრს არ განიხილავს.
მეორე არის სუფთა ფრონტის სრული ტექსტის ძებნა.
ამჟამად, ElasticLunr.js სუფთა ფრონტის სრული lunrjs
ძიება მოიცავს lunrjs
lunrjs
ინდექსების შექმნის ორი გზა არსებობს და ორივეს აქვს საკუთარი პრობლემები.
წინასწარ ჩაშენებული ინდექსის ფაილები
იმის გამო, რომ ინდექსი შეიცავს სიტყვებს ყველა დოკუმენტიდან, ის დიდი ზომისაა. როდესაც დოკუმენტი ემატება ან იცვლება, უნდა ჩაიტვირთოს ახალი ინდექსის ფაილი. ეს გაზრდის მომხმარებლის ლოდინის დროს და მოიხმარს უამრავ გამტარობას.
ჩატვირთეთ დოკუმენტები და შექმენით ინდექსები
ინდექსის შექმნა გამოთვლითი ინტენსიური ამოცანაა ინდექსის ყოველ ჯერზე წვდომისას გამოიწვიოს აშკარა ჩამორჩენა და მომხმარებლის ცუდი გამოცდილება.
lunrjs
ის გარდა, არსებობს სხვა სრული ტექსტის საძიებო გადაწყვეტილებები, როგორიცაა :
fusejs გამოთვალეთ მსგავსება სტრიქონებს შორის საძიებლად.
ამ გადაწყვეტის შესრულება უკიდურესად ცუდია და არ შეიძლება გამოყენებულ იქნას სრული ტექსტის საძიებლად (იხ Fuse.js ხანგრძლივ შეკითხვას სჭირდება 10 წამზე მეტი, როგორ მოხდეს მისი ოპტიმიზაცია? ).
TinySearch გამოიყენეთ Bloom ფილტრი საძიებლად, არ შეიძლება გამოყენებულ იქნას პრეფიქსის საძიებლად (მაგალითად, შეიყვანეთ goo
, ძიება good
, google
) და ვერ მიაღწიეთ მსგავს ავტომატურ ეფექტს.
არსებული გადაწყვეტილებების ნაკლოვანებების გამო, i18n.site
შეიმუშავა ახალი სუფთა ფრონტის სრული ტექსტის საძიებო გადაწყვეტა, რომელსაც აქვს შემდეგი მახასიათებლები :
gzip
შეფუთვის შემდეგ არის 6.9KB
(შედარებისთვის, lunrjs
-ის ზომა არის 25KB
).indexedb
ზე დაყრდნობით, რომელიც ნაკლებ მეხსიერებას იკავებს და სწრაფია.ქვემოთ დეტალურად იქნება წარმოდგენილი 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:
/\p{P}/
არის { გამოხატულება, რომელიც ემთხვევა ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _
ნიშნებს. | } . .</p><ul><li>
split('.')არის იმის გამო, რომ ბრაუზერის
Firefoxსიტყვის სეგმენტაცია არ არის სეგმენტი
. ` .
ობიექტის შენახვის 5 ცხრილი შეიქმნა IndexedDB
-ში :
word
: id -doc
: id - url - დოკუმენტის ვერსიის ნომერიdocWord
დოკუმენტის მასივი id - : idprefix
პრეფიქსის : - სიტყვის idrindex
: id - დოკუმენტი id : ხაზების ნომრების მასივიჩაატარეთ დოკუმენტის url
და ვერსიის ნომერი ver
მასივი და მოძებნეთ დოკუმენტი არსებობს თუ არა ცხრილში doc
თუ ის არ არსებობს, შექმენით ინვერსიული ინდექსი. ამავდროულად, ამოიღეთ ინვერსიული ინდექსი იმ დოკუმენტებისთვის, რომლებიც არ იყო გადაცემული.
ამ გზით შეიძლება მიღწეული იქნას ინკრემენტული ინდექსირება და მცირდება გაანგარიშების რაოდენობა.
ფრონტალური ურთიერთქმედებისას, ინდექსის ჩატვირთვის პროგრესის ზოლი შეიძლება გამოჩნდეს, რათა თავიდან იქნას აცილებული ჩამორჩენა პირველად ჩატვირთვისას იხილეთ "პროგრესის ზოლი ანიმაციით, ერთიან progress + Pure css Implementation" ინგლისური / ჩინური .
პროექტი 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
ქეშის გამო, მას შემდეგ რაც მომხმარებელი შეასრულებს ძიებას, მთელი ვებსაიტი, ძიების ჩათვლით, ხელმისაწვდომია ოფლაინში.
i18n.site
-ის სუფთა წინა საძიებო გადაწყვეტა ოპტიმიზებულია MarkDown
დოკუმენტისთვის.
ძიების შედეგების ჩვენებისას გამოჩნდება თავის სახელი და დაწკაპუნებისას თავში ნავიგაცია მოხდება.
ინვერსიული სრული ტექსტის ძიება განხორციელებულია მხოლოდ წინა ბოლოში, სერვერი არ არის საჭირო. ის ძალიან შესაფერისია მცირე და საშუალო ზომის ვებსაიტებისთვის, როგორიცაა დოკუმენტები და პირადი ბლოგები.
i18n.site
ღია წყაროს თვითგანვითარებული სუფთა ფრონტ-ენდის ძიება, მცირე ზომის და სწრაფი რეაგირება, აგვარებს მიმდინარე სუფთა ფრონტ-ენდის სრული ტექსტის ძიების ხარვეზებს და უზრუნველყოფს მომხმარებლის უკეთეს გამოცდილებას.