Elasticsearch: un motor de búsqueda flexible

¿Qué es Umbraco Examine?

Examine es una abstracción de Lucene.Net y es usado por Umbraco para indexar y buscar contenido de Umbraco. La última versión de Examine usa Lucene.Net 3.0.3, que fue lanzada en 2012. La última versión de Lucene.Net es 4.8.

Cuando se trabaja con Examine para sitios web más exigentes hay una serie de problemas. Por ejemplo, la implementación de Lucene en la plataforma .NET cuando se compara con la versión original Java de Lucene está bastante desactualizada, Lucene.net está en 4.8 y la versión java está en 8.2.0.

La última versión de Lucene.Net tiene muchas mejoras de rendimiento y un mejor soporte multilingüe, en particular para los idiomas CJK (chino, japonés y coreano), a saber, el análisis morfológico en lugar de la tokenización estándar.

Examine es un proveedor problemático cuando el sitio web utiliza una configuración de alta disponibilidad con equilibrio de carga, ya que Examine se basa en archivos y se pueden obtener problemas de bloqueo de archivos en una configuración con equilibrio de carga.

Para Umbraco v8 y v7 hay un almacenamiento de blob de Azure para Examine, sin embargo esto es todavía experimental.

ACTUALIZACIÓN: El paquete Examine.AzureDirectory compatible con la v7 fue lanzado el 11 de febrero de 2020. De todos modos, v8 es todavía un paquete experimental.

Uno de los puntos fuertes de Examine es que hace que trabajar con indexación/búsqueda con Lucene sea mucho más fácil que trabajar con Lucene en bruto, sin embargo esta facilidad viene con una fuerte unión entre Examine y Lucene. Así que cuando Lucene se actualiza, no es tan sencillo como actualizarlo en Examine, requiere muchos cambios en Examine.

Queremos la flexibilidad de Examine pero también queremos las últimas novedades de la última versión de Lucene.

¿Qué es Elasticsearch y por qué se usa?

Elasticsearch es un proveedor de búsqueda de alto rendimiento que soporta la replicación y la reconstrucción sin tiempo de inactividad. Es perfecto para CJK y tiene soporte para muchos más idiomas. Fue diseñado como una búsqueda de todo tipo de datos (texto, numérico, geográfico, estructurado y no estructurado). Elastic también soporta muchos tipos diferentes de consultas desde Lucene hasta consultas SQL.

Además, a diferencia de Examine, Elastic proporciona grandes herramientas de desarrollo, como Kibana, que permiten simular consultas, depurarlas y analizar índices. Elastic también está diseñado para una alta disponibilidad, lo que significa equilibrio de carga, replicación, reindexación sin tiempo de inactividad y más.

La historia detrás del proyecto

La idea de construir un proveedor de Examine Elastic surgió cuando vi una presentación sobre la búsqueda en Umbraco v7 en el Festival Polaco de 2018, donde Ismail Mayat presentó un POC de un indexador para v7 que utilizaba el rastreo de contenido. Después de la presentación, estaba buscando una mejor manera de hacerlo, sin usar procesos externos para indexar el contenido.

Encontré algunas fuentes útiles. Primero fue un paquete llamado 'Umbraco. Elasticsearch', creado por Phil Oyston, y un artículo llamado 'Elasticating Examine - un proveedor de exámenes experimentales', escrito por Tristan Thompson. Ninguna de las dos soluciones me generó satisfacción, ya que la primera era crear una lógica innecesaria alrededor de Umbraco y reimplantar el proveedor de Examine, y la segunda era solo para los índices personalizados y requería algunos cambios para trabajar con Umbraco.

El paquete V7

Para Umbraco v7, revisé todos los paquetes de Elastic disponibles y decidí no usarlos como base para mi proyecto. En mi opinión, no era un buen enfoque ya que estaba reimplementando la indexación, la gestión y otras opciones que solo reemplazaría en Umbraco en lugar de tener todavía índices en dos lugares (Umbraco Examine Files y Elastic Instance).

En ese momento, la solución propuesta por Tristan Thompson se acercaba más a mi idea, ya que solo creaba una capa de traducción entre Examine y Elastic. Decidí continuar mi trabajo basado en lo que ya estaba funcionando en ese proveedor experimental.

Uno de los primeros cambios que hice fue pasar la versión de Elastic a 6.5 y empezar a trabajar para permitir la indexación de todo tipo de contenidos como Medios, Contenido y Miembros. En ese momento, todo funcionaba y decidí comenzar a reemplazar el índice interno con Elastic. Aquí encontré algunos pequeños problemas:

  • Como estábamos usando solo versiones publicadas del contenido, la búsqueda no siempre era relevante para el contenido real que no estaba publicado.
  • El índice no podía mostrar el estado de salud en el Backoffice de Umbraco.
  • Todas las propiedades del documento fueron movidas al objeto de las propiedades y, debido a esa operación, todas las propiedades tenían que usar un prefijo en el nombre de los campos del índice.
  • Si una implementación estuviera basada completamente en el NEST, no sería compatible con las consultas de Umbraco Lucene.

Empecé por resolver un problema con la implementación de consultas NEST/Lucene, donde decidí exponer dos formas de consulta:

Métodos de búsqueda

Snippet 1 Métodos de búsqueda

 

¿Por qué abandoné ese proyecto?

  • Umbraco v7 no fue diseñado para soportar proveedores personalizados, y en esa versión solo se podía hacer que funcionaran de una manera hacky, como reimplementar la lógica de búsqueda en el Backoffice.
  • Cualquier actualización de Umbraco podía romper la compatibilidad de los paquetes ya que se basaba en la funcionalidad principal de Umbraco, así que cualquier cambio detendría al proveedor.
  • No había ninguna abstracción en Examine que facilitara el mantenimiento del paquete con Umbraco v7.
  • La implementación de ISearchableTree no era algo que usaría para reemplazar los proveedores de búsqueda del Backoffice, ya que aquí hay que reimplantar toda la lógica de búsqueda, y no creo que esta sea una buena manera de hacerlo. Creo que ISearchableTree solo debería usarse en casos de búsqueda de backoffice personalizada, que no es un reemplazo de la básica.

Umbraco V8

Después de abandonar el proyecto hablé con algunas personas sobre cómo sería de genial tener una mejor opción para hacer esto en Umbraco, y cómo incluso estaba buscando en el código fuente de Umbraco cómo cambiar las partes del código duro para que sean más abstractas y extensibles.

En ese momento, estaba hablando con Shannon de la sede central de Umbraco, y me sugirió que en una nueva versión de Umbraco harían cambios que me permitirían continuar mi proyecto. Decidí basar esto en el código de Azure Search, ya que era un ejemplo de cómo usar la nueva capa de abstracción en Umbraco.

¿Dónde está mi archivo de configuración?

Umbraco v8 cambió la configuración de Examine de archivos de configuración a código.

En lugar de usar la forma anticuada (que yo prefiero) de los archivos de configuración, tenemos una nueva y brillante forma programática de cambiar la configuración de Examine.

Hubo algunas discusiones sobre los pros y los contras de esa solución, pero en el momento en que comencé a trabajar en ese proveedor, todavía no había una forma documentada de cambiar nada en Examine config. Estaba siguiendo una sugerencia de la gente de GitHub, pero unas cuantas veces tuve que pasar tiempo haciendo ingeniería inversa sobre cómo Umbraco manejaba la Inyección de Dependencia, la composición y la configuración de Examine.

Cómo cambiar los índices a través de los componentes

Como la nueva versión cambió la forma de manejar los ajustes de cambio en Umbraco, tuve que averiguar cómo manejar el cambio de Examinar a Elastic en el código fuente. Como en la primera parte, se requería averiguar cómo deshabilitar el componente de Examinar, que adjunta los índices básicos. Como Umbraco estaba usando UmbracoIndex, que hereda de LuceneIndex, tuve que reimplementar los Content Populators, que rellenan el contenido entre todos los índices creados en base a ElasticSearchIndex.

Registrar proveedor personalizado

Snippet 2 Registrar proveedor personalizado

 

Mantente cerca de Umbraco y emula los eventos

Umbraco proporciona algunos eventos por defecto en los índices y no será compatible con la mayor parte del código de Umbraco, tengo que emular los campos de Lucene aunque no los esté usando en absoluto. Los campos de Lucene no son cómodos para trabajar con ellos ya que, en oposición a la mayoría de los objetos, no proporcionan el tipo real de datos. Como solo tienes que trabajar con una cadena, terminas convirtiendo todos los tipos que necesitas para encadenar dinámicamente cuando alguien los obtiene del Diccionario del Documento:

Emulación de dos métodos de la lista de campos

Snippet 3 Emulación de dos métodos de la lista de campos

 

Como se muestra en el tercer ejemplo, estoy emulando dos métodos de la lista actual de campos en Document from Lucene.Net.

Planes para el futuro

Como quiero trabajar con Elastic en todos los proyectos posibles, creo que como parte de los cambios futuros me centraré en ofrecer la mejor experiencia al desarrollador, e intentaré reimplementar todo lo posible para apoyar las consultas de NEST en lugar de las de Lucene dentro de mis proveedores.

También estoy planeando investigar el código fuente de Umbraco y proponer cambios que permitan a los desarrolladores utilizar una mejor abstracción en el núcleo de Umbraco.

Puedes encontrar el archivo del paquete en el siguiente enlace

 

¿Quieres más información?