Reine Front-End-invertierte Volltextsuche
Originallink: https://i18n.site/blog/tech/search
Sequenz
Nach mehreren Wochen der Entwicklung unterstützt i18n.site (ein rein statisches mehrsprachiges Markdown-Übersetzungs- und Website-Erstellungstool) jetzt die reine Front-End-Volltextsuche.
In diesem Artikel wird die technische Implementierung der reinen Front-End-Volltextsuche von i18n.site vorgestellt. Besuchen Sie i18n.site, um die Suchfunktion kennenzulernen.
Code ist Open-Source: Suchkernel / Interaktive Schnittstelle
Ein Überblick über serverlose Volltextsuchlösungen
Für kleine und mittlere rein statische Websites wie Dokumente/persönliche Blogs ist der Aufbau eines selbst erstellten Volltextsuche-Backends zu aufwändig, und eine dienstfreie Volltextsuche ist die häufigere Wahl.
Serverlose Volltextsuchlösungen sind in zwei Hauptkategorien unterteilt:
Beim ersten handelt es sich um Drittanbieter von Suchdiensten wie algolia.com, die Frontend-Komponenten für die Volltextsuche anbieten.
Solche Dienste erfordern eine Bezahlung basierend auf dem Suchvolumen und sind aufgrund von Compliance-Problemen für Benutzer auf dem chinesischen Festland häufig nicht verfügbar.
Sie können nicht offline oder in Intranets verwendet werden und unterliegen erheblichen Einschränkungen. In diesem Artikel wird nicht näher darauf eingegangen.
Die zweite Kategorie ist die reine Front-End-Volltextsuche.
Zu den derzeit gängigen reinen Front-End-Volltextsuchtools gehören lunrjs und ElasticLunr.js (eine sekundäre Entwicklung, die auf lunrjs basiert).
lunrjs verfügt über zwei Methoden zum Erstellen von Indizes, beide mit ihren eigenen Problemen.
- Vorgefertigte Indexdateien
Da der Index alle Wörter aus den Dokumenten enthält, ist er groß.
Jedes Mal, wenn ein Dokument hinzugefügt oder geändert wird, muss eine neue Indexdatei geladen werden.
Dies erhöht die Wartezeit der Benutzer und verbraucht eine erhebliche Menge an Bandbreite.
- Dokumente laden und Indizes im Handumdrehen erstellen
Das Erstellen eines Index ist eine rechenintensive Aufgabe, und die Neuerstellung bei jedem Zugriff kann zu spürbaren Verzögerungen führen, was zu einer schlechten Benutzererfahrung führt.
Neben lunrjs gibt es noch andere Volltextsuchlösungen, wie zum Beispiel:
fusejs, das sucht, indem es die Ähnlichkeit zwischen Zeichenfolgen berechnet.
Diese Lösung weist eine schlechte Leistung auf und ist nicht für die Volltextsuche geeignet (siehe Fuse.js. Lange Abfrage dauert mehr als 10 Sekunden, wie optimiert man sie?).
TinySearch, das einen Bloom-Filter für die Suche verwendet, kann keine Präfixsuchen durchführen (z. B. Eingabe von „goo“, um nach „Gut“ oder „Google“ zu suchen) und keinen automatischen Vervollständigungseffekt erzielen.
Aufgrund der Nachteile bestehender Lösungen hat i18n.site eine neue reine Front-End-Volltextsuchlösung mit den folgenden Funktionen entwickelt:
- Unterstützt die mehrsprachige Suche bei kompakter Größe; Der Suchkernel ist, wenn er mit gzip gepackt ist, nur 6,9 KB groß (im Vergleich dazu ist lunrjs 25 KB groß)
- Erstellt einen invertierten Index basierend auf IndexedDB mit geringer Speichernutzung und schneller Leistung
- Wenn Dokumente hinzugefügt/geändert werden, werden nur die hinzugefügten oder geänderten Dokumente neu indiziert, wodurch sich der Berechnungsaufwand verringert
- Unterstützt die Präfixsuche und ermöglicht die Echtzeitanzeige von Suchergebnissen während der Eingabe durch den Benutzer
- Offline-Verfügbarkeit
Details zur technischen Implementierung von i18n.site werden unten vorgestellt.
Mehrsprachige Wortsegmentierung
Wortsegmentierung verwendet den nativen Intl.Segmenter des Browsers, der von allen gängigen Browsern unterstützt wird.
Der Coffeescript-Code für die Wortsegmentierung lautet wie folgt:
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()
Wo:
-
/p{P}/ ist ein regulärer Ausdruck, der Satzzeichen übereinstimmt, einschließlich: ! " # $ % & ' ( ) * , - . / : ; < = > ? @ [ ] ^ _ { | } ~. .
- split('.' ) liegt daran, dass die Firefox-Browser-Wortsegmentierung keine Segmentierung durchführt.` .
Indexkonstruktion
Fünf Objektspeichertabellen werden in IndexedDB erstellt:
- Wort: id - Wort
- doc: id – Dokument-URL – Dokumentversionsnummer
- docWord: Dokument-ID – Array von Wort-IDs
- Präfix: Präfix – Array von Wort-IDs
- rindex: Wort-ID – Dokument-ID – Array von Zeilennummern
Durch die Übergabe eines Arrays aus Dokument-URL und Versionsnummer ver wird die Dokumenttabelle auf die Existenz des Dokuments überprüft. Wenn er nicht vorhanden ist, wird ein invertierter Index erstellt. Gleichzeitig wird der invertierte Index für nicht übergebene Dokumente entfernt.
Diese Methode ermöglicht eine inkrementelle Indizierung und reduziert so die Rechenlast.
In the front-end interface, a progress bar for index loading can be displayed to avoid lag during the initial load. See "Animated Progress Bar, Based on a Single progress + Pure CSS Implementation" English / Chinese.
IndexedDB High Concurrent Writing
The project is developed based on the asynchronous encapsulation of IndexedDB, idb.
IndexedDB reads and writes are asynchronous. When creating an index, documents are loaded concurrently to build the index.
To avoid data loss due to concurrent writes, you can refer to the following coffeescript code, which adds a ing cache between reading and writing to intercept competitive writes.
`coffee
pusher = =>
ing = new Map()
(table, id, val)=>
id_set = ing.get(id)
if id_set
id_set.add val
returnid_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
Nach dem Login kopierenrindexPush = pusher()
prefixPush = pusher()
`Prefix Real-Time Search
To display search results in real-time as the user types, for example, showing words like words and work that start with wor when wor is entered.
The search kernel uses the prefix table for the last word after segmentation to find all words with that prefix and search sequentially.
An anti-shake function, debounce (implemented as follows), is used in the front-end interaction to reduce the frequency of searches triggered by user input, thus minimizing computational load.
js
export default (wait, func) => {
var timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(func.bind(this, ...args), wait);
};
}
Precision and Recall
The search first segments the keywords entered by the user.
Assuming there are N words after segmentation, the results are first returned with all keywords, followed by results with N-1, N-2, ..., 1 keywords.
The search results displayed first ensure query precision, while subsequent loaded results (click the "Load More" button) ensure recall.
On-Demand Loading
To improve response speed, the search uses the yield generator to implement on-demand loading, returning results after each limit query.
Note that after each yield, a new IndexedDB query transaction must be opened for the next search.
Prefix Real-Time Search
To display search results in real-time as the user types, for example, showing words like words and work that start with wor when wor is entered.
The search kernel uses the prefix table for the last word after segmentation to find all words with that prefix and search sequentially.
An anti-shake function, debounce (implemented as follows), is used in the front-end interaction to reduce the frequency of searches triggered by user input, thus minimizing computational load.
js
export default (wait, func) => {
var timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(func.bind(this, ...args), wait);
};
}
Offline Availability
The index table does not store the original text, only words, reducing storage space.
Highlighting search results requires reloading the original text, and using service worker can avoid repeated network requests.
Also, because service worker caches all articles, once a search is performed, the entire website, including search functionality, becomes offline available.
Optimization for Displaying MarkDown Documents
The pure front-end search solution provided by i18n.site is optimized for MarkDown documents.
When displaying search results, the chapter name is shown, and clicking navigates to that chapter.
Summary
The pure front-end implementation of inverted full-text search, without the need for a server, is very suitable for small to medium-sized websites such as documents and personal blogs.
i18n.site's open-source self-developed pure front-end search is compact, responsive, and addresses the various shortcomings of current pure front-end full-text search solutions, providing a better user experience.
Das obige ist der detaillierte Inhalt vonReine Front-End-invertierte Volltextsuche. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Häufig gestellte Fragen und Lösungen für das Ticket-Ticket-Ticket-Ticket in Front-End im Front-End-Entwicklungsdruck ist der Ticketdruck eine häufige Voraussetzung. Viele Entwickler implementieren jedoch ...

JavaScript ist der Eckpfeiler der modernen Webentwicklung. Zu den Hauptfunktionen gehören eine ereignisorientierte Programmierung, die Erzeugung der dynamischen Inhalte und die asynchrone Programmierung. 1) Ereignisgesteuerte Programmierung ermöglicht es Webseiten, sich dynamisch entsprechend den Benutzeroperationen zu ändern. 2) Die dynamische Inhaltsgenerierung ermöglicht die Anpassung der Seiteninhalte gemäß den Bedingungen. 3) Asynchrone Programmierung stellt sicher, dass die Benutzeroberfläche nicht blockiert ist. JavaScript wird häufig in der Webinteraktion, der einseitigen Anwendung und der serverseitigen Entwicklung verwendet, wodurch die Flexibilität der Benutzererfahrung und die plattformübergreifende Entwicklung erheblich verbessert wird.

Es gibt kein absolutes Gehalt für Python- und JavaScript -Entwickler, je nach Fähigkeiten und Branchenbedürfnissen. 1. Python kann mehr in Datenwissenschaft und maschinellem Lernen bezahlt werden. 2. JavaScript hat eine große Nachfrage in der Entwicklung von Front-End- und Full-Stack-Entwicklung, und sein Gehalt ist auch beträchtlich. 3. Einflussfaktoren umfassen Erfahrung, geografische Standort, Unternehmensgröße und spezifische Fähigkeiten.

Wie fusioniere ich Array -Elemente mit derselben ID in ein Objekt in JavaScript? Bei der Verarbeitung von Daten begegnen wir häufig die Notwendigkeit, dieselbe ID zu haben ...

JavaScript zu lernen ist nicht schwierig, aber es ist schwierig. 1) Verstehen Sie grundlegende Konzepte wie Variablen, Datentypen, Funktionen usw. 2) Beherrschen Sie die asynchrone Programmierung und implementieren Sie sie durch Ereignisschleifen. 3) Verwenden Sie DOM -Operationen und versprechen Sie, asynchrone Anfragen zu bearbeiten. 4) Vermeiden Sie häufige Fehler und verwenden Sie Debugging -Techniken. 5) Die Leistung optimieren und Best Practices befolgen.

Diskussion über die Realisierung von Parallaxe -Scrolling- und Elementanimationseffekten in diesem Artikel wird untersuchen, wie die offizielle Website der Shiseeido -Website (https://www.shiseeido.co.jp/sb/wonderland/) ähnlich ist ...

Zu den neuesten Trends im JavaScript gehören der Aufstieg von Typenkripten, die Popularität moderner Frameworks und Bibliotheken und die Anwendung der WebAssembly. Zukunftsaussichten umfassen leistungsfähigere Typsysteme, die Entwicklung des serverseitigen JavaScript, die Erweiterung der künstlichen Intelligenz und des maschinellen Lernens sowie das Potenzial von IoT und Edge Computing.

Eingehende Diskussion der Ursachen des Unterschieds in der Konsole.log-Ausgabe. In diesem Artikel wird die Unterschiede in den Ausgabeergebnissen der Konsolenfunktion in einem Code analysiert und die Gründe dafür erläutert. � ...
