Blog des Gens Compliqués

L'ElasticSearch du pauvre: SQLite Fulltext Search

15/05/2019 10:07:59+02:00|Par DkVZ
3 minutes de lecture (facile)

Qui d'autre a une véritable fonction recherche qui se comporte un peu bizarrement sur son site, hein?

Bon, Wordpress a une fonction recherche, mais qui réagit INSTANTANEMENT? Non MDameSieur!

Voyez par vous-mêmes en inscrivant des termes de recherche, par exemple "bruit de prout", sur cette page.

Tout a commencé parce que chipotais avec ElasticSearch parce que parfois on s'ennuie comme quand on est à une soirée intime chez des gens et qu'on se fait chier alors on tripote cette masse en céramique qui est posée sur la table et qui s'avère en fait être un moule des dents de l'arrière grand père. C'est plus fort que nous.

Qu'est-ce que ça fait ElasticSearch? Ca cherche. C'est un service REST que vous lui postez une requête et il vous répond tout de suite. Et c'est ça qui est important, le tout de suite. Le service utilise des index similaires à des index de recherche fulltext pour produire ses résultats.

A vrai dire je ne suis pas certain de comprendre ce qui est différent, à part le support natif de sharding, et, plus globalement de mise-à-l'échelle sur plusieurs noeuds.

Quand on creuse un petit peu il apparaît clairement qu'ES pousse la recherche fulltext bien plus loin que ce qu'un index fulltext de moteur de DB est capable de faire et le tout avec des tas d'options pour créer des index optimisés à certains types de recherche.

Par contre, tout ça est loin d'être gratuit en terme de ressources.

Mon blog tourne sur une pomme de terre à chair ferme mais très modeste dans sa fermeté (?) ce qui n'est pas un problème puisque je suis admin système au départ et spécialiste en architectures avec un très étonnant ratio performances/prix de l'hébergement.

Si comme moi vous voulez tenter l'aventure VPS-à-4€-par-mois, la meilleure base de donnée pour une application de type blog, c'est SQLite.

Oui, je sais qu'il y a des tiers gratuits pour firebase et autres MongoDB Atlas et j'ai pas le temps de vous expliquer à quel point c'est puant par rapport à votre SQLite local parce que c'est censé être une brève et c'est à nouveau déjà tout sauf bref.

Sinon, contrairement à ce qu'on pourrait croire, Redis n'est pas une trop mauvaise idée non plus. MongoDB, MySQL et les autres sont à éviter.

Vous pouvez même coupler Wordpress à SQLite. Mais là aussi je conseille pas parce que Wordpress = PHP qui est probablement la techno web la plus inefficace au monde. Et je dis ça alors que PHP est un des langages que je connais le mieux.

Comme j'utilisais déjà SQLite, j'ai cherché si par hasard ils avaient un système d'index fulltext. Ils ont ça. Ils en ont même, genre, 5 versions.

En pratique il s'agit de créer une table "virtuelle" depuis un client SQLite d'une version suffisamment élevée pour supporter cette version du moteur fulltext.

CREATE VIRTUAL TABLE articles_ft USING FTS5(id, title, content);

Si j'ai bien compris, toutes les colonnes sont de type texte ou en tous cas test-indexable-en-fulltext. Néanmoins, par la magie de SQLite, les jointures fonctionnent quand même, je peux donc relier la version indexée d'un article au véritable article dans la table articles.

Vous pouvez ensuite peupler la table virtuelle. Personnellement j'y mets une version des articles sans aucun contenu HTML.

Il est ensuite possible de balancer une requête fulltext un peu comme un query de base sur ElasticSearch de cette manière:

SELECT * FROM articles_ft WHERE articles_ft MATCH 'bruit de prout' ORDER BY rank;

Remarquez qu'on utilise le nom de la table virtuelle dans la clause WHERE et qu'on ordonne par rapport à une colonne spécifique au fulltext qui représente l'indice de qualité des résultats.

Tout ça est expliqué ici en mieux: https://www.sqlite.org/fts5.html

Je ne vais pas rentrer dans les détails mais vous avez quelques fonctions de bases comme snippet() qui permettent d'isoler des extraits du contenu et tout ça et que je me suis empressé d'utiliser.

En pratique on peut aussi chercher des demi-mots, utiliser NOT, OR, AND et tout ce genre de choses. Pour l'instant je me suis limité à un drôle de trucs qui fonctionne avec des mots complets et qui du coup est totalement alien par rapport à un véritable moteur de recherche mais bon... On se refait pas.

Au niveau taille de la DB après création des index, je dirais à la grosse louche que j'ai eu une augmentation de 70%. Ceci dit ma DB ne fait que 2.6MB. Il faut y passer l'aspirateur de temps en temps.

Toujours est-il que c'est extrêmement simple à mettre en place et les réponses sont immédiates même sur un stockage qui se traine et la DB est très portable par nature (le backup est trivial au possible).

Est-ce que ce serait une autre histoire avec 1GB d'index? Peut-être bien. Mais peut-être pas non plus, surtout sur une machine qui a très peu de mémoire.

C'est une prochaine super idée de comparaison entre ElasticSearch et un truc de pauvre basé sur SQLite.

Commentaires

Il faut JavaScript activé pour écrire des commentaires ici

#1

Francois
21/05/2021 20:46:52+02:00
Super! Je vais essayer de combiner ca avec ceci https://phiresky.github.io/blog/2021/hosting-sqlite-databases-on-github-pages/

Ajouter un commentaire

Votre commentaire a été ajouté
(enfin, je pense)