Maison > interface Web > js tutoriel > le corps du texte

Recherche en texte intégral inversée purement frontale

Mary-Kate Olsen
Libérer: 2024-10-14 14:27:29
original
245 Les gens l'ont consulté

Lien original : https://i18n.site/blog/tech/search

Séquence

Après plusieurs semaines de développement, i18n.site (un outil de traduction multilingue et de création de sites Web purement statique) prend désormais en charge la recherche frontale en texte intégral pure.

Recherche en texte intégral inversée purement frontaleRecherche en texte intégral inversée purement frontale

Cet article partagera la mise en œuvre technique de la recherche en texte intégral purement frontale d'i18n.site. Visitez i18n.site pour découvrir la fonctionnalité de recherche.

Le code est open-source : Noyau de recherche / Interface interactive

Un aperçu des solutions de recherche en texte intégral sans serveur

Pour les sites Web purement statiques de petite et moyenne taille tels que les documents/blogs personnels, la création d'un moteur de recherche en texte intégral auto-construit est trop lourde, et la recherche en texte intégral sans service est le choix le plus courant.

Les solutions de recherche en texte intégral sans serveur sont divisées en deux catégories principales :

Le premier implique des fournisseurs de services de recherche tiers comme algolia.com qui proposent des composants frontaux pour la recherche en texte intégral.

Ces services nécessitent un paiement en fonction du volume de recherche et sont souvent indisponibles pour les utilisateurs en Chine continentale en raison de problèmes de conformité.

Ils ne peuvent pas être utilisés hors ligne ou sur intranet et présentent des limitations importantes. Cet article ne sera pas développé davantage.

La deuxième catégorie est la recherche frontale en texte intégral pure.

Actuellement, les outils de recherche en texte intégral front-end courants incluent lunrjs et ElasticLunr.js (un développement secondaire basé sur lunrjs).

lunrjs propose deux méthodes pour créer des index, toutes deux avec leurs propres problèmes.

  1. Fichiers d'index prédéfinis

Étant donné que l'index comprend tous les mots des documents, il est de grande taille.
Chaque fois qu'un document est ajouté ou modifié, un nouveau fichier d'index doit être chargé.
Cela augmente le temps d'attente des utilisateurs et consomme une quantité importante de bande passante.

  1. Chargement de documents et création d'index à la volée

La création d'un index est une tâche gourmande en calcul, et sa reconstruction à chaque accès peut entraîner des retards notables, conduisant à une mauvaise expérience utilisateur.


En plus de lunrjs, il existe d'autres solutions de recherche en texte intégral, telles que :

fusejs, qui recherche en calculant la similarité entre les chaînes.

Cette solution a des performances médiocres et n'est pas adaptée à la recherche en texte intégral (voir Fuse.js Une requête longue prend plus de 10 secondes, comment optimiser ?).

TinySearch, qui utilise un filtre Bloom pour la recherche, ne peut pas effectuer de recherches de préfixes (par exemple, saisir goo pour rechercher good ou google) et ne peut pas obtenir un effet de saisie semi-automatique.

En raison des inconvénients des solutions existantes, i18n.site a développé une nouvelle solution de recherche en texte intégral purement frontale avec les fonctionnalités suivantes :

  1. Prend en charge la recherche multilingue, avec une taille compacte ; le noyau de recherche, lorsqu'il est fourni avec gzip, ne fait que 6,9 ​​Ko (en comparaison, lunrjs fait 25 Ko)
  2. Construit un index inversé basé sur IndexedDB, avec une faible utilisation de la mémoire et des performances rapides
  3. Lorsque des documents sont ajoutés/modifiés, seuls les documents ajoutés ou modifiés sont réindexés, réduisant ainsi le nombre de calculs
  4. Prend en charge la recherche par préfixe, permettant l'affichage en temps réel des résultats de recherche au fur et à mesure que l'utilisateur tape
  5. Disponibilité hors ligne

Les détails de la mise en œuvre technique d'i18n.site seront présentés ci-dessous.

Segmentation de mots multilingues

La segmentation des mots utilise l'Intel.Segmenter natif du navigateur, qui est pris en charge par tous les navigateurs grand public.

Recherche en texte intégral inversée purement frontale

Le code coffeescript pour la segmentation des mots est le suivant :

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()
Copier après la connexion

Où :

  • /p{P}/ est une expression régulière qui correspond aux signes de ponctuation, notamment : ! " # $ % & ' ( ) * , - . / : ; < = > ? @ [ ] ^ _ { | } ~. .

    • split('.' )c'est parce que la segmentation des mots du navigateur Firefox ne segmente pas.` .

    Construction de l'indice

    Cinq tables de stockage d'objets sont créées dans IndexedDB :

    • mot : identifiant - mot
    • doc : id - URL du document - numéro de version du document
    • docWord : identifiant du document - tableau d'identifiants de mots
    • préfixe : préfixe - tableau d'identifiants de mots
    • rindex : identifiant du mot - identifiant du document - tableau de numéros de ligne

    En transmettant un tableau d'URL du document et de numéro de version ver, la table doc est vérifiée pour l'existence du document. S'il n'existe pas, un index inversé est créé. Simultanément, l'index inversé des documents non transmis est supprimé.

    Cette méthode permet une indexation incrémentielle, réduisant ainsi la charge de calcul.

    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
    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
    
    Copier après la connexion

    rindexPush = 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.

    Recherche en texte intégral inversée purement frontale

    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.

    Recherche en texte intégral inversée purement frontale

    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.

    Recherche en texte intégral inversée purement frontale

    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.

    Recherche en texte intégral inversée purement frontale

    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.

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal