Todo lo que pasa cuando pulsas Enter en mi buscador
La versión técnica: del evento de teclado al ranking, con el índice de 735 fragmentos, BM25 con k1=1,5 y b=0,75, el empujón por idioma y las decisiones que tomé por el camino. Para quien ya leyó la versión sin jerga y quiere ver los engranajes.

Hace unos días conté sin jerga cómo funciona el buscador de esta web. Esta es la otra mitad: la versión con los engranajes a la vista, número a número, para quien quiera construirse uno igual.
El índice se construye en cada publicación. Un script recorre proyectos, herramientas, artículos y páginas, y trocea todo en fragmentos de tamaño de párrafo. Ahora mismo salen 735 fragmentos que cubren unas cien páginas en dos idiomas; cada uno guarda su texto, su URL, su título y su idioma. Todo eso viaja como un único JSON estático que la CDN comprime — el navegador lo pide una sola vez, la primera vez que abres el buscador, y se queda cacheado.
La tokenización decide qué es una palabra. Antes de comparar nada, pregunta y fragmentos pasan por el mismo molinillo: minúsculas, fuera acentos (así "qué" y "que" coinciden), y fuera las palabras vacías de cada idioma — artículos, preposiciones y demás relleno que aparece en todas partes y no distingue nada. La lista de vacías es doble, español e inglés, porque el índice mezcla ambos.
El ranking es BM25, con sus dos diales de serie. Para cada término de tu pregunta, cada fragmento suma una puntuación que combina tres cosas: cuán raro es el término en todo el índice (los términos raros mandan), cuántas veces aparece en el fragmento (con saturación: la quinta aparición vale mucho menos que la primera, eso lo controla k1=1,5) y cuán largo es el fragmento (los largos acumulan apariciones por pura extensión, y eso se penaliza con b=0,75). Usé los valores clásicos de la literatura y no los toqué: con un índice así de pequeño, afinarlos no movía el resultado.
Una decisión propia: el empujón por idioma. Si preguntas en español, los fragmentos en español multiplican su puntuación por 1,35. No es teoría: sin él, una pregunta en español sobre un proyecto devolvía a veces la versión inglesa de la misma página, que es correcta pero incómoda. El factor salió de probar: 1,2 no bastaba para desempatar y 1,5 enterraba resultados ingleses legítimamente mejores.
El remate: deduplicar por URL. Varios fragmentos de la misma página pueden colarse en el top. Antes de mostrar nada, se queda solo el mejor fragmento de cada URL, y te enseño cuatro páginas distintas en vez de cuatro trozos de la misma. Es una línea de código y es la diferencia entre un buscador que ayuda y uno que se repite.
Lo que mide de verdad. Todo el ciclo — tokenizar la pregunta, puntuar 735 fragmentos, ordenar y deduplicar — corre en el hilo principal en bien menos de un frame; el único coste real es la primera descarga del índice. No hay servidor, no hay API, no hay coste por consulta y tu pregunta no sale del navegador. Para el tamaño de este sitio, cualquier cosa más sofisticada sería resolver un problema que no tengo — y en el laboratorio puede verse qué compra exactamente el siguiente escalón, cuando los vectores sustituyen a las palabras contadas.

