Qu'est-ce qu'un moyen rapide et efficace d'implémenter le composant côté serveur pour une fonctionnalité de saisie semi-automatique dans une zone de saisie HTML? J'écris un service de saisie semi-automatique des requêtes utilisateur dans la boîte de recherche principale de notre interface web, et les complétions sont affichées dans une liste déroulante ajax-powered. Les données que nous utilisons sont simplement une grande table de concepts que notre système connaît, ce qui correspond à peu près à l'ensemble des titres de pages wikipedia. Pour ce service, la rapidité est évidemment d'une importance capitale, car la réactivité de la page Web est importante pour l'expérience de l'utilisateur.Implémentation autocomplète côté serveur
La mise en œuvre actuelle charge simplement tous les concepts en mémoire dans un ensemble trié et effectue une simple recherche de journal (n) sur une séquence de touches utilisateur. Le jeu de mots est ensuite utilisé pour fournir des correspondances supplémentaires au-delà de la correspondance la plus proche. Le problème avec cette solution est qu'elle n'est pas évolutive. Il est actuellement en cours d'exécution par rapport à la limite d'espace de segment VM (j'ai défini -Xmx2g, ce qui correspond à peu près à nos machines 32 bits), ce qui nous empêche d'étendre notre table de concepts ou d'ajouter plus de fonctionnalités. Passer à des machines virtuelles 64 bits sur des machines disposant de plus de mémoire n'est pas une option immédiate.
J'ai hésité à commencer à travailler sur une solution basée sur disque car je crains que le temps de recherche de disque ne tue les performances. Existe-t-il des solutions possibles qui me permettront de mieux évoluer, que ce soit entièrement en mémoire ou avec des implémentations rapides appuyées par des disques?
: Edits
@Gandalf: Pour notre cas d'utilisation, il est important que le l'autocomplétion est complet et est non seulement une aide supplémentaire pour l'utilisateur. Quant à ce que nous sommes en train de compléter, il s'agit d'une liste de paires de types de concepts. Par exemple, les entrées possibles sont [("Microsoft", "Société de logiciels"), ("Jeff Atwood", "Programmeur"), ("StackOverflow.com", "Site Web")]. Nous utilisons Lucene pour la recherche complète une fois qu'un utilisateur sélectionne un élément de la liste de saisie semi-automatique, mais je ne suis pas encore sûr que Lucene fonctionnerait bien pour la saisie semi-automatique elle-même.
@Glen: Aucune base de données n'est utilisée ici. Quand je parle d'une table, je veux simplement dire la représentation structurée de mes données.
@Jason Day: Mon implémentation d'origine de ce problème consistait à utiliser un Trie, mais le problème de mémoire était pire que l'ensemble trié en raison du besoin d'un grand nombre de références d'objet. Je lis sur les arbres de recherche ternaires pour voir si cela pourrait être utile.
Pourriez-vous nous en dire un peu plus sur ce que vous êtes « auto-achèvement ». Pourquoi tant de termes? Y a-t-il des réponses plus évidentes qui satisferaient 90% des requêtes de vos utilisateurs, plutôt que de charger toutes les possibilités? – Gandalf
Je ne peux pas dire avec certitude si Lucene répondra à vos besoins, mais sur cet ensemble de données de taille, je doute vraiment que vous n'obtiendrez pas de temps de requête de secondes sur un index Lucene optimisé. Selon la manière dont l'index est configuré, vous pouvez même le stocker en mémoire. – Gandalf
Un Trie standard est en effet très gourmand en mémoire, pour des ensembles plus grands, vous voulez utiliser un Trie compacté qui réduit considérablement l'empreinte de la mémoire. Les optimisations supplémentaires englobent l'initialisation paresseuse des valeurs de noeud et les bonnes structures de données pour les ensembles enfants/valeur. Il y a quelque temps, j'ai créé une [Java autocomplete library] (https://github.com/fmmfonseca/completely) capable de gérer des ensembles de données très volumineux (10 000 000+) et répond efficacement aux recherches exactes et approximatives. –