¿Cuál es una manera rápida y eficiente para implementar el componente del lado del servidor para una función de autocompletado en un cuadro de entrada html?autocompletar aplicación del lado del servidor
Estoy escribiendo un servicio para autocompletar las consultas de los usuarios en el cuadro de búsqueda principal de la interfaz web, y las terminaciones se muestran en un menú desplegable impulsado por Ajax. Los datos con los que estamos ejecutando consultas son simplemente una gran tabla de conceptos que nuestro sistema conoce, que coincide aproximadamente con el conjunto de títulos de páginas de wikipedia. Para este servicio, obviamente, la velocidad es de suma importancia, ya que la capacidad de respuesta de la página web es importante para la experiencia del usuario.
La implementación actual simplemente carga todos los conceptos en la memoria en un conjunto ordenado, y realiza una simple búsqueda de registro (n) en una pulsación de tecla del usuario. El tail tail se usa para proporcionar coincidencias adicionales más allá de la coincidencia más cercana. El problema con esta solución es que no escala. Actualmente se está ejecutando en contra del límite de espacio de almacenamiento dinámico de la máquina virtual (he configurado -Xmx2g, que es lo máximo que podemos impulsar en nuestras máquinas de 32 bits), y esto nos impide expandir nuestra tabla de conceptos o agregar más funcionalidades. Cambiar a máquinas virtuales de 64 bits en máquinas con más memoria no es una opción inmediata.
He dudado en comenzar a trabajar en una solución basada en disco, ya que me preocupa que el tiempo de búsqueda de disco mate el rendimiento. ¿Hay posibles soluciones que me permitan escalar mejor, ya sea completamente en memoria o con algunas implementaciones rápidas respaldadas por disco?
ediciones:
@Gandalf: Para nuestro caso de uso es importante que el de la terminación automática es integral y no es simplemente ayuda adicional para el usuario. En cuanto a lo que estamos completando, es una lista de pares de conceptos conceptuales. Por ejemplo, las posibles entradas son [("Microsoft", "Compañía de software"), ("Jeff Atwood", "Programador"), ("StackOverflow.com", "Sitio web")]. Estamos utilizando Lucene para la búsqueda completa una vez que el usuario selecciona un elemento de la lista de autocompletar, pero todavía no estoy seguro de que Lucene funcione bien para la autocompleta.
@Glen: No hay bases de datos están siendo utilizados aquí. Cuando estoy hablando de una tabla solo me refiero a la representación estructurada de mis datos.
@Jason Day: Mi implementación original para este problema fue usar un Trie, pero la saturación de memoria con eso era en realidad peor que el conjunto ordenado debido a la necesidad de una gran cantidad de referencias de objetos. Leeré en los árboles de búsqueda ternarios para ver si podría ser de utilidad.
¿Podría decirnos un poco más acerca de lo que son "auto-completar". ¿Por qué tantos términos? ¿Hay otros más obvios que satisfagan el 90% de las consultas de los usuarios, en lugar de cargar todas las posibilidades? – Gandalf
No puedo decir con certeza si Lucene se ajustará a tus necesidades, pero en ese conjunto de datos de tamaño, dudo mucho que no obtengas segundos tiempos de consulta en un índice optimizado de Lucene. Según cómo esté configurado el índice, es posible que incluso pueda almacenarlo en la memoria. – Gandalf
Un Trie estándar es de hecho muy intensivo en memoria, para conjuntos más grandes que desea utilizar un Trie compactado que reduce en gran medida la huella de memoria. Las optimizaciones adicionales incluyen la inicialización diferida de los valores de nodo y las estructuras de datos correctas para los conjuntos de valores/hijos. Hace un tiempo, creé una [biblioteca de autocompletado de Java] (https://github.com/fmmfonseca/completely) capaz de manejar conjuntos de datos muy grandes (10,000,000+) y responde eficientemente búsquedas exactas y aproximadas. –