Elasticsearch

Article Wikipedia : https://en.wikipedia.org/wiki/Elasticsearch

Documentation : https://www.elastic.co/docs

Voir aussi le fork : OpenSearch.


Journaux liées à cette note :

Journal du samedi 21 décembre 2024 à 16:10 #iteration, #personal-knowledge-management, #search-engine, #ElasticSearch

Je viens d'améliorer l'implémentation du moteur de recherche de mon sklein-pkm-engine.

Voici un screencast de présentation du résultat :

Le commit de changement : https://github.com/stephane-klein/sklein-pkm-engine/commit/71210703fe626bd455b2ec7774167d9a637e4972

Je suis passé de :

query_string: {
    query: queryString,
    default_field: "content_html"
}

à ceci :

multi_match: {
	query: queryString,
	fields: ["title^2", "content_html"],
	fuzziness: "AUTO",
	type: "best_fields"
}

Les fonctionnalités de recherche d'Elasticsearch sont nombreuses. Pour les parcourir, je conseille ce point d'entrée de la documentation Search in Depth.
Même après avoir fini mon implémentation de la fonction recherche, je dois avouer que je tâtonne sur le sujet. Je suis loin de maitriser le sujet.

Au départ, après lecture de ce paragraphe :

If you don’t need to support a query syntax, consider using the match query. If you need the features of a query syntax, use the simple_query_string query, which is less strict.

source

J'ai fait un refactoring de query_string vers simple_query_string (lien vers la documentation).

Mon objectif était d'arriver à implémenter la fonctionnalité Query-Time Search-as-You-Type avec de la recherche floue (fuzzy).

J'ai commencé par essayer la syntax foobar~* mais j'ai appris qu'il n'était pas possible d'utiliser ~ (fuzzy) en couplé avec * 😔 (documentation vers la syntax). Sans doute pour de bonnes raisons, liées à des problèmes de performance.

J'ai ensuite découpé ma requête en 3 conditions :

baseQuery.body.query.bool.must.push({
	bool: {
		should: [
			{
				simple_query_string: {
					query: queryString,
					fields: ["content_html"],
					boost: 3
				}
			},
			{
				simple_query_string: {
					query: queryString.split(' ').map(word => (word.length >= 3) ? `${word}*` : undefined).join(' ').trim(),
					fields: ["content_html"],
					boost: 1
				}
			},
			{
				simple_query_string: {
					query: queryString.split(' ').map(
						word => {
							if (word.length >= 5) { return `${word}~2`; }
							else if (word.length >= 3) { return `${word}~1`; }
							else return undefined;
						}
					).join(' ').trim(),
					fields: ["content_html"],
					boost: 1
				}
			}
		],
		minimum_should_match: 1
	}
}

Cette implémentation fonctionne, mais je rencontrais des problèmes de performance aléatoires que je n'ai pas pris le temps d'essayer de comprendre la cause.

À force de tâtonnement, j'ai fini par choisir la solution basée sur multi_match (documentation de référence) :

multi_match: {
	query: queryString,
	fields: ["title^2", "content_html"],
	fuzziness: "AUTO",
	type: "best_fields"
}

Documentation de référence du paramètre fuzziness : Fuzzy query.

Documentation de la valeur AUTO : Common options - Fuzziness

Malheureusement, ici aussi, je ne peux pas utiliser fuzziness avec phrase_prefix :

The fuzziness parameter cannot be used with the phrase or phrase_prefix type.

source

En finissant cette note, je viens de découvrir cet exemple dans la documentation.

J'ai l'impression de comprendre qu'en utilisant le tokenizer ngram je pourrais faire des Fuzzy Search sans utiliser l'option fuzziness 🤔.

J'ai commencé l'implémentation dans la branche ngram-tokenizer mais je m'arrête là pour aujourd'hui. En tout, ce weekend, j'ai passé 4h30 sur ce sujet 😮.
J'espère tester cette implémentation d'ici à quelques jours.

Je souhaite aussi essayer prochainement de migrer de Elasticsearch vers OpenSearch.

Journal du lundi 28 octobre 2024 à 14:56 #graphql, #WebDev

Je rassemble ici quelques notes au sujet de projet Hasura.

À l'origine, Hasura était uniquement un moteur GraphQL open-source qui se branchait directement sur une base de données PostgreSQL. Le projet a commencé en 2018, bien que le site web soit plus ancien — 2015.
D'après le dépôt GitHub, les premiers développeurs d'Hasura sont Shahidh K Muhammed, Vamshi Surabhi, Aravind Shankar et Rakesh Emmadi, tous basés à Bangalore, en Inde.

En 2019, dans un cadre professionnel, j'ai choisi d'utiliser un autre moteur GraphQL : PostGraphile.

Début 2020, j'avais également identifié Hasura et Supabase comme alternatives.

J'avais choisi d'utiliser PostGraphile pour plusieurs raisons :

  • Supabase était encore un jeune projet, lancé en octobre 2019.
  • Hasura était codé en Haskell, un langage que je ne maîtrise pas. En revanche, PostGraphile, développé en JavaScript, m'inspirait plus confiance, car je savais que j'avais les compétences nécessaires si je devais intervenir sur son code source, par exemple, pour corriger un bug.
  • D'autre part, PostGraphile n'était pas financé par des Venture capital, ce qui m'inspirait bien plus confiance sur son avenir que Supabase et Hasura.
  • J'apprécie énormément la façon de travailler de Benjie. J'apprécie sa manière d'organiser ses projets, ses documentations et ses choix techniques. Je pense que notre doctrine est assez similaire.

Quatre plus tard, je constate que PostGraphile a choisi de rester concentré sur un seul objectif : être un moteur GraphQL, tandis que Supabase et Hasura, bénéficiant d'un financement par des Venture capital, ont diversifié leurs offres.

Alors que PostGraphile se limite au support de PostgreSQL, Hasura peut se connecter à Mysql, MongoDB, Clickhouse, Elasticsearch
Et d'après la documentation, Hasura permet d'exposer, en plus d'une API GraphQL, une API REST (RESTified Endpoints).

Journal du samedi 05 octobre 2024 à 11:38 #monitoring, #JaiDécouvert

Dans ce thread Reddit, #JaiDécouvert :

Cloud-native search engine for observability.. An open-source alternative to Datadog, Elasticsearch, Loki, and Tempo.

openITCOCKPIT is an Open Source system monitoring tool built for different monitoring engines like Nagios, Naemon and Prometheus.

🚀 10x easier, 🚀 140x lower storage cost, 🚀 high performance, 🚀 petabyte scale - Elasticsearch / Splunk / Datadog alternative for 🚀 (logs, metrics, traces, RUM, Error tracking, Session replay).

Journal du mercredi 02 octobre 2024 à 18:07 #iteration

Nouvelle #iteration du Projet 11 - "Première version d'un moteur web PKM".

J'ai traité les tâches décrites dans ma dernière note.

  • Comme me l'a signalé à plusieurs reprises Alexandre, je dois améliorer le rendu responsive sur smartphone. Jusqu'à présent, je n'ai pas encore consacré de temps à ce sujet.
  • Je dois améliorer le script d'import des données dans Elasticsearch. Pour le moment, ici, je commence par supprimer toutes les données avant d'effectuer l'importation des données.
    Problème : les pages ne sont plus accessibles pendant l'exécution de ce script.

J'ai enfin publié sklein-pkm-engine sur https://notes.sklein.xyz.

En mars 2024, j'écrivais :

Pour le moment, j'utilise Obsidian Quartz pour déployer https://notes.sklein.xyz.

Est-ce que j'en suis satisfait ? Pour le moment, la réponse est non, parce que je ne le maitrise pas assez.

J'ai une grande envie d'implémenter une version personnelle basée sur SvelteKit et Apache Age, mais j'essaie de ne pas tomber dans ce Yak!.

Début mai 2024, je suis tombé dans ce Yak!, j'y ai consacré 93 heures en tout, soit l'équivalent d'environ 15 jours de travail étalés sur 8 semaines.

J'ai enfin supprimé Obsidian Quartz

J'ai changé plusieurs fois de direction :

Je viens d'essayer de réaliser un screencast de présentation de la version actuelle de sklein-pkm-engine, mais le résultat de mon discours était vraiment trop déstructuré pour être publié. J'essaierai de publier un screencast prochainement.

Je viens de tenter de réaliser un screencast pour présenter la version actuelle de sklein-pkm-engine, mais mon discours était trop désorganisé pour être publié. Je souhaite enregistrer une nouvelle version prochainement.

Prochains objectifs concernant le projet sklein-pkm-engine :

Journal du mardi 01 octobre 2024 à 11:55 #iteration

Nouvelle #iteration du Projet 11 - "Première version d'un moteur web PKM".

Dans ma dernière itération du 31 août 2024, j'écrivais ceci :

Voici quelque erreur d'User Interface que je souhaite corriger.

Sur ce screenshot, les notes actuellement séparé par des <hr /> ne sont pas facilement identifiable.

Depuis, j'ai travaillé dans la branche experimentation-ui et pour le moment, j'ai le résultat suivant :

Je pense que les délimitations des notes sont maintenant mieux identifiables.

Problème User Interface que j'ai identifié : je pense que la présence d'un lien sur le titre de la note n'est pas facilement "découvrable".


Mon objectif est toujours le suivant :

Maintenant mon objectif est d'apporter le minimum de petite amélioration me permettant de remplacer l'instance notes.sklein.xyz propulsé actuellement par Obsidian Quartz par une version propulsé par sklein-pkm-engine.

-- from

Voici la liste des choses que je dois implémenter pour atteindre cet objectif.

  • Comme me l'a signalé à plusieurs reprises Alexandre, je dois améliorer le rendu responsive sur smartphone. Jusqu'à présent, je n'ai pas encore consacré de temps à ce sujet.
  • Je dois améliorer le script d'import des données dans Elasticsearch. Pour le moment, ici, je commence par supprimer toutes les données avant d'effectuer l'importation des données.
    Problème : les pages ne sont plus accessibles pendant l'exécution de ce script.

Je pense qu'après avoir traité ces deux tâches, je pourrais abandonner Obsidian Quartz et seulement ensuite implémenter toutes les idées pour améliorer mon Personal knowledge management "viewer".

Journal du jeudi 29 août 2024 à 13:23 #iteration, #projet

Voici les nouveautés depuis ma dernière itération du Projet 11 - "Première version d'un moteur web PKM".

Ce commit contient le résultat du travail du Projet 13, c'est-à-dire le refactoring de PostgreSQL vers Elasticsearch ainsi que la page /src/routes/search qui permet à la fois d'effectuer une recherche sur le contenu des notes et un filtrage de type and sur les tags.

Une démo est visible ici https://notes.develop.sklein.xyz/

Ma Developer eXperience avec Elasticsearch est excellente. J'ai trouvé toutes les fonctionnalités dont j'avais besoin.

Je pense que mon utilisation des Fleeting Note n'est pas la bonne. Je pense que les notes que je qualifie de Fleeting Note sont en réalité des Diary notes ou Journal notes.

J'ai donc décidé de :

  • [x] Renommer partout fleeting_note en journal_notes

Après implémentation, j'ai réalisé que j'ai fait l'erreur de mélanger l'implémentation de le page qui affiche la liste des notes antéchronologiques et la page de recherche.

Pour être efficace, le résultat de la page recherche doit être affiché en fonction du scoring de la recherche, alors que les pages listes de notes par date de publication.

J'ai donc décidé de :

  • [x] Implémenter une page /diaries/ (pour la cohérence des path en anglais, je préfère "diaries" à "journaux") qui affiche une liste de notes de type Diary notes ;
    • [x] Cette page doit permettre un filtrage par tags
  • [x] Implémenter une page /notes/ qui affiche une liste des notes qui ne sont pas de type Diary notes, comme des Evergreen Note, Hub note
    • [x] Contrairement à la page liste des Diary notes, cette page de liste ne doit pas afficher le contenu des notes, mais seulement le titre des notes ;
    • [x] Je propose de classer ces titres de notes par ordre alphabétique ;
    • [x] Je propose aussi de séparer ces notes par lettre, A, B… c'est-à-dire un index alphabétique.
    • [x] Cette page doit permettre un filtrage par tags
  • [x] Refactoring la page /search/ pour ordonner le résultat de la recherche par scoring.
    • [x] Cette page doit afficher le contenu des notes avec highligthing ;
    • [x] Cette page doit permettre un filtrage sur les types de notes, pour le moment Diary notes et Evergreen Note.
    • [x] Cette page doit permettre un filtrage par tags

Au moment où j'écris ces lignes, je ne sais pas encore comment je vais gérer les opérateurs or, (.

Pour le moment, le filtrage multi tags est effectué avec des and.

Journal du dimanche 25 août 2024 à 11:00 #JaiDécouvert, #docker-compose, #coding, #OnMaPartagé

Alexandre m'a fait découvrir la fonctionnalité Compose Watch ajoutée en septembre 2023 dans la version 2.22.0 de docker compose.

Compose supports sharing a host directory inside service containers. Watch mode does not replace this functionality but exists as a companion specifically suited to developing in containers.

More importantly, watch allows for greater granularity than is practical with a bind mount. Watch rules let you ignore specific files or entire directories within the watched tree.

For example, in a JavaScript project, ignoring the node_modules/ directory has two benefits:

  • Performance. File trees with many small files can cause high I/O load in some configurations

  • Multi-platform. Compiled artifacts cannot be shared if the host OS or architecture is different to the container

    -- from

Je suis très heureux de l'introduction de cette fonctionnalité, même si je n'ai pas encore eu l'occasion de la tester. Bien que je trouve qu'elle arrive un peu tardivement 😉.

Je suis surpris d'observer que cette fonction a généré très peu de réaction sur Hacker News 🤔.

Je n'ai rien trouvé non plus sur Reddit, ni sur Lobster 🤔.

Sans doute pour cela que je n'ai pas vu la sortie de cette fonctionnalité.

Je pense avoir retrouvé la première Pull Request de la fonctionnalité compose watch : [ENV-44] introduce experimental watch command (skeletton) #10163.
Je constate que compose watch est basé sur fsnotify.
Je constate ici qu'un système de "debounce" est implémenté.
Je pense que c'est cette fonction qui effectue la copie des fichiers, mais je n'en suis pas certain et je ai mal compris son fonctionnement.

Entre 2015 et 2019, j'ai rencontré de nombreux problèmes de performance liés aux volumes de type "bind" sous MacOS (et probablement aussi sous MS Windows) :

volumes:
  - ./src/:/src/

Les performances étaient désastreuses pour les projets Javascript avec leurs node_modules volumineux. Exécuter des commandes telles que npm install ou npm run build prenait parfois 10 à 50 fois plus de temps que sur un système natif ! Je précise que ce problème de performance était inexistant sous GNU Linux.

Pour résoudre ce problème pour les utilisateurs de MacOS, j'ai exploré plusieurs stratégies de development environment, comme l'utilisation de Vagrant avec différentes méthodes de montage, dont certaines reposaient sur une approche similaire à celle de Compose Watch, c'est-à-dire la surveillance des fichiers (fsnotify…) et leur copie.

N'ayant trouvé aucune solution pleinement satisfaisante, j'ai finalement adopté la stratégie Asdf, puis Mise, qui me convient parfaitement aujourd'hui.

Cela signifie que, dans mes environnements de développement, je n'utilise plus Docker pour les services sur lesquels je développe, qu'ils soient implémentés en JavaScript, Python ou Golang...
En revanche, j'utilise toujours Docker pour les services complémentaires tels que PostgreSQL, Redis, Elasticsearch, etc.

Est-ce que la fonctionnalité Compose Watch remettra en question ma stratégie basée sur Mise ? Pour l'instant, je ne le pense pas, car je ne rencontre aucun inconvénient majeur avec ma configuration actuelle et l'expérience développeur (DX) est excellente.

Journal du samedi 17 août 2024 à 15:00 #JeMeDemande

#JeMeDemande comment Elasticsearch gère le support Highlighting (search-engine) avec du contenu qui intègre initialement des balises HTML 🤔.

J'ai trouvé la réponse dans cet article Elastic Search: Highlighting Text That Contains HTML Tags.

-- from

#JeMeDemande également si pg_search, Typesense et Meilisearch peuvent réaliser la même chose que ce qui est décrit dans Elastic Search: Highlighting Text That Contains HTML Tags.

En ce qui concerne Typesense, j'ai consulté l'issue Feature Request - Ignore any HTML tags when searching but still return response with HTML included, ce qui me laisse penser que cette fonctionnalité n'est pas prise en charge.

Pour Meilisearch, la discussion Ignore HTML tags at search m'a également conduit à la conclusion que cette fonctionnalité n'est pas encore implémentée. J'ai aussi appris qu'Algolia permet d'ignorer les balises HTML lors de la recherche : Algolia ignores HTML tags during search.

Quant à pg_search, mes recherches sur les mots-clés HTML dans les dépôts pg_search et Tantivy (Tantivy) n'ont rien donné. Il semble donc que la fonctionnalité de surlignage du texte contenant des balises HTML ne soit pas prise en charge par pg_search.

Contenu de ce constat, je vais peut-être redonner une chance à Elasticsearch malgré mon aversion pour la JVM 🤔.