brief: | Το i18n.site υποστηρίζει πλέον την αναζήτηση πλήρους κειμένου χωρίς διακομιστή.
Αυτό το άρθρο εισάγει την εφαρμογή της καθαρής τεχνολογίας αναζήτησης πλήρους κειμένου στο μπροστινό μέρος, συμπεριλαμβανομένου του ανεστραμμένου ευρετηρίου που δημιουργήθηκε από το IndexedDB, της αναζήτησης προθέματος, της βελτιστοποίησης τμηματοποίησης λέξεων και της υποστήριξης πολλών γλωσσών.
Σε σύγκριση με τις υπάρχουσες λύσεις, η αμιγώς μπροστινή αναζήτηση πλήρους κειμένου του i18n.site είναι μικρή σε μέγεθος και γρήγορη, κατάλληλη για μικρού και μεσαίου μεγέθους ιστότοπους, όπως έγγραφα και ιστολόγια, και είναι διαθέσιμη εκτός σύνδεσης.
& από αρκετές εβδομάδες ανάπτυξης, markdown i18n.site
Αυτό το άρθρο θα μοιραστεί την τεχνική υλοποίηση της i18n.site
καθαρής αναζήτησης πλήρους κειμένου για να i18n.site το αποτέλεσμα αναζήτησης.
Για μικρού και μεσαίου μεγέθους αμιγώς στατικούς ιστότοπους, όπως έγγραφα/προσωπικά ιστολόγια, η δημιουργία ενός πλήρους κειμένου αναζήτησης που έχει κατασκευαστεί μόνος σας είναι πολύ βαριά και η αναζήτηση πλήρους κειμένου χωρίς υπηρεσίες είναι η πιο κοινή επιλογή.
Οι λύσεις αναζήτησης πλήρους κειμένου χωρίς διακομιστή χωρίζονται σε δύο μεγάλες κατηγορίες:
Πρώτον, algolia.com πάροχοι υπηρεσιών αναζήτησης τρίτων παρέχουν στοιχεία διεπαφής για αναζήτηση πλήρους κειμένου.
Τέτοιες υπηρεσίες απαιτούν πληρωμή με βάση τον όγκο αναζήτησης και συχνά δεν είναι διαθέσιμες στους χρήστες στην ηπειρωτική Κίνα λόγω ζητημάτων όπως η συμμόρφωση με τον ιστότοπο.
Δεν μπορεί να χρησιμοποιηθεί εκτός σύνδεσης, δεν μπορεί να χρησιμοποιηθεί στο intranet και έχει μεγάλους περιορισμούς. Αυτό το άρθρο δεν συζητά πολλά.
Το δεύτερο είναι η καθαρή αναζήτηση πλήρους κειμένου στο front-end.
Προς το παρόν, οι ElasticLunr.js αμιγώς μπροστινές αναζητήσεις πλήρους κειμένου lunrjs
lunrjs
lunrjs
Υπάρχουν δύο τρόποι δημιουργίας ευρετηρίων και και οι δύο έχουν τα δικά τους προβλήματα.
Προκατασκευασμένα αρχεία ευρετηρίου
Επειδή το ευρετήριο περιέχει λέξεις από όλα τα έγγραφα, είναι μεγάλο σε μέγεθος. Κάθε φορά που προστίθεται ή τροποποιείται ένα έγγραφο, πρέπει να φορτώνεται ένα νέο αρχείο ευρετηρίου. Θα αυξήσει τον χρόνο αναμονής του χρήστη και θα καταναλώσει πολύ εύρος ζώνης.
Φορτώστε έγγραφα και δημιουργήστε ευρετήρια εν κινήσει
Η δημιουργία ενός ευρετηρίου είναι μια εντατική υπολογιστική εργασία.
Εκτός από το lunrjs
, υπάρχουν και κάποιες άλλες λύσεις αναζήτησης πλήρους κειμένου, όπως :
fusejs υπολογίστε την ομοιότητα μεταξύ των συμβολοσειρών για αναζήτηση.
Η απόδοση αυτής της λύσης είναι εξαιρετικά κακή και δεν μπορεί να χρησιμοποιηθεί για αναζήτηση πλήρους κειμένου (δείτε Fuse.js Το μεγάλο ερώτημα διαρκεί περισσότερα από 10 δευτερόλεπτα, πώς να το βελτιστοποιήσετε; ).
TinySearch χρησιμοποιήστε το φίλτρο Bloom για αναζήτηση, δεν μπορεί να χρησιμοποιηθεί για αναζήτηση προθέματος (για παράδειγμα, πληκτρολογήστε goo
, αναζήτηση good
, google
) και δεν μπορείτε να επιτύχετε παρόμοιο αποτέλεσμα αυτόματης ολοκλήρωσης.
Λόγω των ελλείψεων των υπαρχουσών λύσεων, i18n.site
ανέπτυξε μια νέα λύση αναζήτησης πλήρους κειμένου καθαρού front-end, η οποία έχει τα ακόλουθα χαρακτηριστικά :
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()
σε:
/\p{P}/
είναι μια κανονική έκφραση που ταιριάζει με τα σημεία στίξης Τα συγκεκριμένα σύμβολα που ταιριάζουν περιλαμβάνουν: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _
{ | } . .</p><ul><li>
split('.')οφείλεται στο ότι η τμηματοποίηση λέξης
Firefoxπρογράμματος περιήγησης δεν τμηματοποιεί
. ` .
Δημιουργήθηκαν 5 πίνακες αποθήκευσης αντικειμένων σε IndexedDB
:
word
λέξεις : id -doc
: id - url - Αριθμός έκδοσης εγγράφουdocWord
Πίνακας εγγράφου id - id :prefix
Πίνακας id - λέξη :rindex
: id - Document id : Πίνακας αριθμών γραμμήςΠεράστε στον πίνακα του εγγράφου url
και του αριθμού έκδοσης ver
και αναζητήστε εάν το έγγραφο υπάρχει στον πίνακα doc
Εάν δεν υπάρχει, δημιουργήστε ένα ανεστραμμένο ευρετήριο. Ταυτόχρονα, αφαιρέστε το ανεστραμμένο ευρετήριο για εκείνα τα έγγραφα που δεν διαβιβάστηκαν.
Με αυτόν τον τρόπο, μπορεί να επιτευχθεί σταδιακή ευρετηρίαση και να μειωθεί το ποσό του υπολογισμού.
Στην αλληλεπίδραση στο μπροστινό μέρος, η γραμμή προόδου φόρτωσης του ευρετηρίου μπορεί να εμφανιστεί για να / η καθυστέρηση κατά τη φόρτωση css πρώτη φορά , progress + .
Το έργο 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
Ανοιχτού κώδικα αμιγώς διεπαφής αναζήτησης που έχει αναπτυχθεί μόνος του, μικρού μεγέθους και γρήγορης απόκρισης, επιλύει τα μειονεκτήματα της τρέχουσας αμιγούς διεπαφής αναζήτησης πλήρους κειμένου και παρέχει καλύτερη εμπειρία χρήστη.