- Tantivy est une bibliothèque rapide de moteur de recherche full-text écrite en Rust, plus proche d’une crate servant à construire un moteur de recherche que d’un serveur de recherche clé en main
- Sa conception est fortement inspirée d’Apache Lucene. Si vous cherchez un serveur alternatif à Elasticsearch ou Apache Solr, il est recommandé de regarder Quickwit, un moteur de recherche distribué construit sur Tantivy
- Parmi ses fonctionnalités : recherche full-text, scoring BM25, requêtes en langage naturel, recherche d’expressions, indexation incrémentale, indexation multithread, répertoire mmap, compression SIMD des entiers, recherche à facettes, champs JSON, collector d’agrégation, etc.
- Le projet fonctionne sur Rust stable, prend en charge Linux, macOS et Windows, et annonce un temps de démarrage inférieur à 10 ms, ce qui le rend adapté aux outils en ligne de commande
- La recherche distribuée est hors du périmètre de Tantivy. Pour modifier un document, il faut supprimer l’ancien puis le réindexer. Les nouveaux documents ne deviennent recherchables qu’après
commit, rechargement de IndexReader et obtention d’un nouveau Searcher
Positionnement et conception de Tantivy
- Tantivy est une bibliothèque rapide de moteur de recherche full-text écrite en Rust
- Ce n’est pas un serveur de moteur de recherche exécutable directement comme Elasticsearch ou Apache Solr, mais une crate permettant de construire ce type de moteur
- Sur le plan de la conception, il est plus proche d’Apache Lucene et s’inspire fortement de son architecture
- Si vous cherchez une alternative à Elasticsearch ou Apache Solr, le projet recommande de consulter le moteur de recherche distribué Quickwit, construit sur Tantivy
Performances et benchmarks
- Tantivy propose des benchmarks séparant les performances selon les types de requêtes et de collections
- Les résultats peuvent varier selon la nature des requêtes et la charge
- Les détails des benchmarks sont disponibles dans le dépôt search-benchmark-game
- D’après la FAQ, sur les benchmarks de latence de recherche, Tantivy est en moyenne environ 2 fois plus rapide que Lucene
Fonctionnalités de recherche et d’indexation
-
Fonctionnalités de recherche
- recherche full-text
- scoring BM25 comme Lucene
- prise en charge des requêtes en langage naturel :
(michael AND jackson) OR "king of pop"
- prise en charge de la recherche d’expressions :
"michael jackson"
- requêtes par plage
- recherche à facettes
- champ JSON
- Aggregation Collector : histogram, range buckets, average, stats metrics
-
Fonctionnalités d’indexation
- prise en charge de l’indexation incrémentale
- prise en charge de l’indexation multithread
- l’indexation de la Wikipédia anglophone prendrait moins de 3 minutes sur un ordinateur de bureau
- configuration possible de l’indexation via term frequency optionnelle et position indexing
- prise en charge de LogMergePolicy with deletes
- API Searcher Warmer fournie
-
Stockage et champs
- prise en charge de mmap directory
- prise en charge des fast fields single-valued et multivalued pour u64, i64, f64
- prise en charge des fast fields
&[u8]
- prise en charge des champs text, i64, u64, f64, dates, ip, bool, hierarchical facet
- la compression du magasin de documents prend en charge LZ4, Zstd et None
Tokenizer et prise en charge des langues
- Le tokenizer est configurable, et le stemming peut être utilisé pour 17 langues de la famille latine
- La prise en charge de tokenizers tiers est également proposée
- Lors de l’implémentation d’un tokenizer pour Tantivy, il faut dépendre de la crate
tantivy-tokenizer-api
Environnement d’exécution et démarrage
- Tantivy fonctionne sur Rust stable
- Les systèmes d’exploitation pris en charge sont Linux, macOS et Windows
- Son temps de démarrage est inférieur à 10 ms, ce qui le rend adapté aux outils en ligne de commande
- Ressources pour commencer
- La compilation locale et les tests se font avec les commandes suivantes
git clone https://github.com/quickwit-oss/tantivy.git
cd tantivy
cargo test
Fonctions hors périmètre et modèle de modification des données
- La recherche distribuée est hors du périmètre de Tantivy
- Si vous avez besoin de recherche distribuée, le projet recommande de consulter Quickwit
- Les données de Tantivy sont immutables
- Pour modifier un document, il faut supprimer le document existant puis le réindexer
- Les documents en cours d’indexation deviennent recherchables après l’appel à
commit sur IndexWriter
- Le
IndexReader existant doit être rechargé pour refléter les modifications
- Les changements ne sont visibles que depuis un
Searcher nouvellement obtenu
Bindings et cas d’usage
- Bindings disponibles pour d’autres langages
- Python : tantivy-py
- Ruby : tantiny
- D’autres bindings peuvent aussi être trouvés sur GitHub, mais ils peuvent être moins bien maintenus
- Exemples d’utilisation de Tantivy
- seshat : base de données/indexeur de messages Matrix
- tantiny : petite recherche full-text pour Ruby
- lnx : moteur de recherche tolérant aux fautes, adaptatif, avec REST API
- Bichon : archiveur d’e-mails Rust léger et haute performance avec WebUI
- Les entreprises indiquées comme utilisant Tantivy sont Etsy, ParadeDB, Nuclia, Humanfirst.ai et Element.io
1 commentaires
Avis de Hacker News
Les personnes qui ont créé cette bibliothèque sont vraiment impressionnantes. L’an dernier, en remplaçant une vieille base de code Python2 AppEngine laissée longtemps à l’abandon, j’ai reconstruit https://progscrape.com [1] par-dessus, et c’est une excellente bibliothèque, incroyablement rapide.
Sur un Raspberry Pi, elle indexe l’ensemble du million d’articles en quelques secondes.
Je fais tourner le service de recherche plein texte sur le Pi à la maison, et même si la charge de pointe reste modeste, de l’ordre de quelques rps, le CPU ne dépasse presque jamais quelques pourcents. J’ai testé la recherche en charge jusqu’à environ 100 rps sur le Pi, et il a tenu. C’était une bibliothèque très utile, quasiment prête à être intégrée telle quelle ; l’équipe a aussi répondu très vite aux rapports de bugs, et les bugs étaient très rares.
Pour voir à quel point la recherche est réactive sur un si petit appareil, cliquez sur les libellés de chaque article. Les requêtes sont pratiquement instantanées, alors qu’elles interrogent jusqu’à 10 ans * 12 mois de shards de recherche : https://progscrape.com/?search=javascript
Pour un projet moderne, je recommanderais de regarder ça plutôt que Lucene. Comme ça scale aussi bien même sur un petit ARM64, il y a de fortes chances que l’expérience soit encore bien meilleure sur des serveurs plus grands.
[1] https://github.com/progscrape/progscrape
Je voulais permettre aux utilisateurs de rechercher dans leurs sauvegardes, et comme j’utilise Rust, Tantivy semblait parfaitement adapté. L’indexation d’un e-mail est tellement rapide que je n’ai même pas eu besoin de la déplacer dans un thread séparé, et la recherche dans des milliers d’e-mails ne semble poser aucun problème.
Si vous avez besoin de recherche dans une application Rust, Tantivy vaut le détour.
Error: PersistError(UnexpectedError("Storage fetch panicked"))s’affiche.Au fond, tout ce dont j’ai besoin, c’est de recherche plein texte.
J’ai découvert Tantivy récemment dans ParadeDB. ParadeDB est une extension Postgres qui vise à remplacer Elastic.
https://github.com/paradedb/paradedb/blob/dev/pg_search/Carg...
Je l’ai découverte en écoutant « Extending Postgres for High Performance Analytics (with Philippe Noël) ».
https://www.youtube.com/watch?v=NbOAEJrsbaM
Et on la retrouve aussi dans le projet principal, Quickwit, qui traite les logs, les traces et bientôt les métriques.
https://github.com/quickwit-oss/quickwit
J’ai utilisé Quickwit avec ClickHouse dans un projet personnel de recherche multilingue, et le résultat a été étonnamment bon. On a enfin une combinaison utilisable pour le chinois, le japonais et le coréen.
https://quickwit.io/docs/guides/add-full-text-search-to-your...
Le
to_tsvectorde PostgreSQL n’a jamais vraiment bien fonctionné pour mon cas d’usage.SELECT * FROM dump WHERE to_tsvector('english'::regconfig, hh_fullname) @@ to_tsquery('english'::regconfig, 'query');J’espère que ça marchera bien. Je pense que je vais automatiquement recommander les articles qui mentionnent Tantivy comme mot-clé.
Nous avons récemment déployé en production Quickwit, basé sur Tantivy et créé par la même équipe, et indexé des dizaines de milliards d’objets ; nous en sommes très satisfaits. La vitesse d’indexation est excellente et la latence des requêtes est compétitive.
Le plus important, c’est que la séparation du calcul et du stockage nous a apporté énormément de valeur. Sans payer pour des serveurs haute performance tournant en continu, nous avons pu lancer un nouveau service de recherche sur des dizaines de milliards d’objets dans un stockage objet, avec même des agrégations complexes, ce qui a rendu possible un nouveau cas d’usage qui aurait autrement coûté assez cher.
Quand le cas d’usage justifie des serveurs haute performance, Quickwit offre aussi la possibilité de mettre les données en cache sur chaque serveur pour améliorer les performances.
Gros bonus : sur Discord, l’équipe aide très vite et avec beaucoup de gentillesse.
Comme autre ressource, il existe aussi l’index de recherche par trigrammes en Go utilisé par etsy/hound[0]. Il est basé sur l’article et le code de Russ Cox, « Regular Expression Matching with a Trigram Index »[1].
[0] https://github.com/hound-search/hound
[1] http://swtch.com/~rsc/regexp/regexp4.html
Selon les besoins, les alternatives à Lucene correspondent aussi à des cas d’usage différents.
Point à noter : il n’est toujours pas possible d’ajouter/supprimer des champs : https://github.com/quickwit-oss/tantivy/issues/470
La seule façon d’ajouter un champ consiste à réindexer toutes les données dans un autre index de recherche.
Je suis tombé sur Tantivy en cherchant une alternative à Meilisearch, qui envoie des données de télémétrie par défaut. C’est davantage un outil pour construire des moteurs de recherche qu’un moteur de recherche à proprement parler, mais la configuration semble assez simple [0]
[0]: https://github.com/quickwit-oss/tantivy-cli
Le SDK Java de Meilisearch était bien aussi. Il n’y avait pas besoin de CLI ni de configuration manuelle : il suffisait de pointer vers des entités de base de données pour indexer toute une table.
Ce serait bien d’avoir ce genre d’approche avec Tantivy.
Tantivy est aussi utilisé pour fournir la recherche plein texte dans LanceDb, un produit intéressant de base de données vectorielle : https://lancedb.github.io/lancedb/fts/
La dernière fois que j’ai regardé, ce n’était possible que via les bindings Python, mais il me semble qu’ils cherchent à implémenter des bindings Rust natifs afin de prendre en charge d’autres plateformes.
Il y a quelques années, j’ai lancé un projet personnel tant Elasticsearch me rendait fou : c’était un monstre gourmand en ressources. Et pourtant, même mon ordinateur personnel dispose de plus de ressources que ce que plusieurs startups bien financées allouent à leurs produits.
J’ai choisi Tantivy pour deux raisons. D’abord, je voulais tout faire en Rust ; ensuite, pour Tantivy lui-même. Les performances sont à 10/10, la documentation est de tout premier ordre et l’expérience d’utilisation de la bibliothèque est excellente.
Malheureusement, le périmètre du projet était trop vaste pour être géré seul sur mon temps libre, alors j’ai abandonné, mais Tantivy reste vraiment excellent.
Je suivais Tantivy depuis un moment. La persévérance des fondateurs et les performances que Tantivy a atteintes récemment sont impressionnantes.
Un grand bravo à toute l’équipe. Je suis fermement convaincu qu’ils atteindront leur objectif.
Pour avoir beaucoup utilisé Lucene et Solr, ce que j’aimerais le plus, c’est la prise en charge des mises à niveau. En général, les index Lucene, Solr ou ES ne peuvent pas être mis à niveau vers une nouvelle version. C’est parfois possible selon les cas, mais je laisse cela de côté pour simplifier.
Dans les grands projets, la réindexation est très coûteuse et parfois presque impossible.
Il existe probablement des cas où c’est tout simplement impossible, par exemple lorsque l’algorithme d’indexation d’un type de données a changé pour un champ indexé avec perte. Mais dans beaucoup de cas, toutes les informations sont encore présentes ; ce serait donc vraiment bien de pouvoir identifier ces index et les mettre à niveau.