Cómo añadí búsqueda con tolerancia a errores tipográficos con OpenSearch y CJK

Las consultas sin resultados estaban acabando con nuestro tiempo de visualización.

Durante un año, TopVideoHub utilizó SQLite FTS5 para la búsqueda. Funcionaba para coincidencias exactas, pero fallaba cuando los usuarios cometían errores tipográficos.

La gente buscaba "demon slyer" en lugar de "demon slayer". Añadían espacios accidentales en títulos en japonés o coreano. Debido a que FTS5 busca tokens exactos, un solo error tipográfico significaba cero resultados. Los usuarios no volvían a buscar; simplemente se marchaban.

Migré nuestra búsqueda de títulos a OpenSearch. Así es como lo solucioné para una audiencia multilingüe.

El problema con la fuzziness estándar

La mayoría de los tutoriales te dicen que uses "fuzziness" para corregir errores tipográficos. Esto funciona para el inglés, pero falla con el texto en chino, japonés y coreano (CJK).

  • La distancia de edición (edit distance) es mala para CJK. Un error tipográfico en CJK a menudo significa usar un carácter completamente erróneo.
  • La fuzziness estándar genera basura semántica. Podría hacer que "fire" coincida con "water" porque están a una edición de distancia.
  • La tokenización es difícil. Los idiomas CJK no utilizan espacios entre palabras.

La solución: un enfoque de campos múltiples

Dejé de tratar todo el texto por igual. Creé un único campo lógico de título que indexa de tres formas distintas:

  • Latín y Romaji: Utilicé una tokenización estándar con la fuzziness activada. Establecí una longitud de prefijo de 1. Esto garantiza que "demon" coincida con "demn", pero que "lemon" no coincida con "demon".
  • Texto CJK: Utilicé un analizador de bigramas CJK y un normalizador ICU. Desactivé la fuzziness. En su lugar, utilicé un umbral de coincidencia mínima del 70%.
  • Autocompletado: Utilicé un campo edge-ngram para habilitar los resultados de búsqueda mientras se escribe (search-as-you-type).

Arquitectura y seguridad de datos

Mantuve SQLite como la única fuente de verdad. OpenSearch actúa como un índice rápido y reconstruible.

  • Utilizo PHP para enviar actualizaciones a OpenSearch en lotes masivos.
  • Nunca ejecuto la indexación durante una solicitud de usuario.
  • Ejecuto un script de Python para comprobar si hay "desviaciones" (drift). Esto asegura que el recuento de OpenSearch coincida con el de SQLite.

Los resultados

El cambio fue masivo:

  • Las consultas sin resultados bajaron del 14% a menos del 3%.
  • Las sesiones de búsqueda se alargaron porque los usuarios encontraban lo que querían de inmediato.
  • La latencia se mantiene baja, en torno a los 40ms.

Si te diriges a una audiencia multilingüe, recuerda: la tolerancia a errores tipográficos y la coincidencia de CJK son dos problemas distintos. Necesitas dos soluciones distintas.

Fuente: https://dev.to/ahmet_gedik778845/how-i-added-typo-tolerant-video-title-search-with-opensearch-and-cjk-3e5d