Motores de búsqueda en Drupal: Search API vs Views

Portada del podcast Drupalízate
Drupalízate es un podcast semanal creado por mí, donde hablo sobre desarrollo web basado en Drupal.
El contenido central es resolver las típicas dudas que pueda tener alguien que tiene o quiere tener una web en Drupal.
Aparte de resolver dudas de "clientes", también se habla de tips, recomendaciones y buenas prácticas para el Developer que recién empiezan en este mundo.
Audio y notas del episodio

Hoy quiero hablar sobre cómo poder implementar tu propio motor de búsqueda en Drupal.

¿Es recomendable usar siempre Views?

¿El módulo Search del Core es útil?

¿Cuando se ha de usar el módulo Search API + Solr + ElasticSearch?

Transcripción automática de este episodio de audio (puede contener errores)

 Hola, una semana más aquí en Drupalizate, donde yo, Robert Menetray, te cuento cosas sobre Drupal, mis peripecias, algunas prácticas, cómo deberías hacer cosas y cómo no deberías hacerlas. Esta semana me quiero centrar en lo que son motores de búsqueda, y no en Google y SEO y estas cosas, sino en montar tu propio motor de búsqueda para tu web, en este caso en un Drupal. Yo creo que sí que hay cosas que se pueden extrapolar a otras tecnologías, pero bueno, yo como siempre me centro en Drupal. A ver, primero de todo, ¿qué es un motor de búsqueda? O cómo lo entiendo yo, que es un motor de búsqueda. Un motor de búsqueda es algo que, digamos, tiene los contenidos de tu web dentro y que permite realizar búsquedas lo más rápido y flexible posible. Eso al final significa que tu web va a mostrar un listado de, por ejemplo, artículos del blog, un listado de cosas, y normalmente habrá uno o más campos de filtrado. Un formulario con un campo de texto, que el usuario que entere en tu web podrá poner un texto allí, darle al botón de filtrar o buscar o enviar formulario, y va a obtener los resultados filtrados, ya sea títulos que contengan esa palabra o descripciones que contengan esa palabra, por ejemplo. O en vez de que sea un campo de texto, puede ser un select list de categorías, por ejemplo, o una combinación. Puede ser que tengas varios campos, uno que sea un select list para marcar categorías, y que tengas un campo de texto. Y que tengas también un checkbox para poder marcar si son publicados o no publicados. De esta forma, al usuario, cuando entre en tu web, le das la oportunidad de filtrar contenidos y ver los artículos del blog que están publicados, los que tengan la categoría X, Y y Z, y al mismo tiempo tengan el título de X palabra. Y eso se extrapola a cualquier campo que tú pongas en tu web, ya sea, por ejemplo, filtros de precios, filtros numéricos varios, o filtros de fechas, lo que sea. Es hiper flexible en ese sentido. Dicha esta explicación, que espero que se me haya entendido. En Drupal, digamos que tenemos tres formas de hacer este tipo de listados con filtros. El primero de todos, el entre comillas más básico y más recomendado para webs entre comillas pequeñas, simples, medianas, es usar views. El módulo views ya lo comenté en episodios pasados. No me voy a presentar mucho en este episodio hablando de views, pero básicamente que sepas que es una de las opciones mayores recomendadas para hacer estas cosas. Tiene sus inconvenientes. Primero de todo, cuando tienes muchos usuarios, muchos de sus concurrentes en la misma web, es una web que tiene muchas visitas diarias, que al mismo tiempo tienes muchos contenidos en tu web, o sea, miles y miles o millones de páginas donde se ha de permitir al usuario poder buscar y encontrar esas páginas. Al mismo tiempo, el buscador tiene uno o varios filtros, con lo cual, al final, como el formulario va a tener datos que va a entrar al usuario, va a poner un texto o una fecha o X, esas consultas si están cacheadas y son las mismas que ha hecho otro usuario, pues están cacheadas. No hay problema en eso. El problema es cuando son consultas únicas que no ha hecho nadie más antes, con lo cual no las puedes cachear o no están cacheadas de antes, con lo cual las consultas son más lentas, se han de ejecutar por primera vez y siempre es más lento porque no está precalculado. Aquí entra, por ejemplo, un caso bastante común, cuando el filtro de campos expuestos permite poner la titul longitud que hemos filtrado por proximidad, por ejemplo. Imagínate que tu proyecto Rupal es una especie de Wallapop o de segunda mano, donde la gente da de alta sus productos y quiere vender de segunda mano y, entre otras cosas, pone allí un campo de, pues, yo estoy en Madrid o estoy en Barcelona, estoy en X ciudad. El usuario cuando entra a la web quiere ver los resultados ordenados por proximidad o poder filtrar de que no quiero ver resultados que estén más lejos de X, yo qué sé, 30 kilómetros. Este tipo de consultas que son geoposicionadas en base a una latitud y longitud, digamos que tienen un alto coste de rendimiento, o sea, digamos, la consulta que se hace a base de datos es bastante lenta, ¿vale? Si tienes uno o dos usuarios no vas a notar el problema, pero cuando tengas muchos usuarios al mismo tiempo haciendo consultas, sí que vas a notar el problema. Y es por el motivo que comentaba antes, la latitud y longitud del usuario no vas a tener dos latitudes y longitudes iguales, a menos que los dos usuarios estén en la misma casa, estén en la misma web, cosa que no es lo más normal, ¿vale? Con lo cual este tipo de búsquedas no están cachadas, es casi recomendable no cacharlas, configurar que no se cachen, porque al final siempre van a ser búsquedas únicas, porque el, a ver cómo digo, la unión de todos los filtros, si quieren buscar que sean coches, que sean de la categoría X, por ejemplo, coches automáticos, o manuales, o lo que sea, que sean de la última semana, y que tengan X filtros más, y además que sean, en base a mi ubicación, una proximidad X, ese conjunto de filtros siempre va a ser distinto que el de otro usuario que busque la misma categoría, misma marca de coche, la misma distancia de ciudad, lo que sea, pero no está en exactamente el mismo punto que otro usuario, con lo cual la consulta base de datos va a ser distinta. Total, esto en views, digamos que deja bastante que desear en temas de rendimiento, ¿vale? ¿Qué otras opciones tenemos si no queremos usar, o digamos que vemos que views se queda corto para nuestro caso de uso? A ver, hay otro caso, hay otro módulo que también viene en el code, igual que views, o sea, no hace falta instalar nada externo, que es el módulo ch, de Drupal, pero yo no lo recomiendo poner, primero porque es muy limitado, segundo porque, por ejemplo, este caso de búsquedas geolocalizadas no lo implementa, o sea, es básicamente para búsquedas de texto. Así que es verdad que soluciona problemas cuando tenemos, que hemos básicamente una búsqueda simple de texto, pero con muchísimos usuarios y muchas páginas donde se han de buscar esos textos, así que es verdad que obtiene mejor rendimiento que una simple views, así que, pero como digo, es muy, no es flexible, ¿vale? Está muy encapsulado y no permite modificar apenas nada, y a menos en mi caso, por los diseños que me llegan, que el cliente quiere que se implementen, el módulo ch se queda corto y al final es mejor usar la tercera opción. ¿Y cuál es la tercera opción? Es el módulo chyapi. El módulo chyapi no está en el code, sino que está en el módulo contribuido, muy usado por webs bastante importantes, ¿vale? Y lo que te permite el módulo chyapi es usar las views, pero que no usen las tablas que vienen por defecto en Drupal de la base de datos, sino que, a ver cómo explico, el módulo chyapi tiene un submódulo, que es el chyapi para base de datos, que te crea unas tablas nuevas en base de datos de Drupal, e indexa los contenidos originales de Drupal ya procesados en esas tablas y los indexa. Y al final, digamos, hace como un precálculo, ¿vale? A ver, por ponerte un ejemplo, a ver cómo explico. Drupal, cuando creas un nodo y añades campos a ese tipo de contenido, a ese tipo de nodo, pues tienes una tabla en base de datos para los nodos, otra tabla en base de datos para cada uno de los campos, y cuando quieres hacer búsquedas que tengan filtros que afecten a varios campos, vas a tener una consulta base de datos que va afectada a varias tablas, lo cual al final, si al final tienes muchas tablas y una consulta que afecta muchos campos, pues tienes una consulta, digamos, un poco monstruosa, ¿vale? Y esto afecta rendimiento. Es uno de los motivos por los que Vigus, digamos, que no escala muy bien. Con chyapi esto lo solucionamos. Al indexar todos los contenidos en la misma tabla, básicamente obtenemos una mejor de rendimiento bastante considerable. Pero bien, aquí hay un pequeño problema. Seguimos metiéndolo todo en base de datos. Tanto usando el módulo Vigus por defecto, como el módulo search, como el módulo chyapi con el submódulo de base de datos, lo estamos metiendo todo, o sea, todas las consultas van contra la base de datos, que normalmente es MySQL. Digamos que esto es un cuello de botella. Si al final tienes muchos usuarios haciendo muchas consultas, la base de datos actúa de cuello de botella y puede hacer de que toda la web en general acabe yendo lenta. ¿Cuál es la solución a esto? Pues hacer que el chyapi, en vez de usar el módulo de base de datos, use otros módulos, como son el de Solar o el de Elasticsearch, que son motores de búsqueda externos a Drupal, que se pueden instalar en el mismo servidor o en un servidor independiente a la web Drupal. El tema es que los datos y las consultas se van a hacer, o sea, los datos se van a copiar, se van a indexar a un servidor externo, a un motor de búsqueda externo, y las consultas se van a hacer contra ese motor de búsqueda externo. Con lo cual el rendimiento del resto de páginas de la web Drupal, como van a tener menos consultas a base de datos, esas páginas no se van a ver afectadas si tienes una alta concurrencia de usuarios. Total, esta es la mejor forma, la que más recomiendo, si tienes un alto volumen de usuarios y un alto volumen de contenidos en la web. Y vamos a poner algunos ejemplos con los que he trabajado yo. Pues intentaré que los que voy a comentar más son más proyectos míos propios que los de clientes, porque por temas de confidencialidad algunas cosas no las puedo comentar. Pero, por ejemplo, temas de geoposicionamiento. En un proyecto que ya hice hace año y pico, más o menos, es babiso.com, es un proyecto propio mío que fue un experimento para ver dónde podía llegar yo con temas de geoposicionamiento. En ese caso yo indexaba contenidos de otras webs, de portales de empleo, son ofertas de empleo, lo que estoy mostrando en esa web. Las proceso, obtengo los datos, porque las búsquedas se permiten hacer por texto, que sea en el título y en el texto de la oferta. Después geoposiciono la oferta en base a un campo. Normalmente ponen esta oferta de empleo es Madrid o Barcelona. Yo cojo eso, lo proceso, lo paso por algunas APIs, obtengo la latitud y longitud de esas ciudades y ya tengo geolocalizada esa oferta de empleo. Con lo cual sé que esta oferta con ese título está en X ciudad en esta latitud, longitud. Y aparte también sacaba algunas palabras y las convertía con categorías, con lo cual tenía filtros de categorías. Total, hacer todo esto y tenerlo en views era inviable, porque al tener más de un millón de ofertas de empleo, la web viva lenta de cojones. O sea, no servía. Views no servía. El módulo search, como digo, no permitía hacer búsquedas geolocalizadas, con lo cual tampoco me servía. El módulo search API con base de datos tenía el mismo problema que con el views o similar, iba algo mejor, pero tardaban demasiados segundos en hacer la consulta. Ya no en randomizar la página, sino solo en hacer la consulta tardaba varios segundos, con lo cual era inviable por usabilidad. O sea, un usuario que entras allí veía que la página tardaba demasiado en cargar. En este caso en concreto, yo opté por usar el Elasticsearch como motor de búsqueda externo. O sea, tenía el Drupal con el search API y el search API se comunicaba con el módulo Elasticsearch Connector y tenía un servidor con Elasticsearch, donde ahí se volcaban todos los contenidos que tenía yo en la web. Y las consultas iban contra este Elasticsearch, con lo cual podía tener millones de resultados que la página cargaba rápido y las consultas iban muchísimo más rápido que antes. Ahora es completamente usable. O sea, nada, dos segundos en tener la página cargada con los resultados ya obtenidos. Y en casos similares, en otros proyectos de algunos clientes se opta por usar Solace por una casuística similar, ya sea por geoposicionamiento o porque simplemente tenemos muchos campos de texto o numéricos o de fechas o lo que sea, que hemos usado en motor de búsqueda externo. ¿Recomiendo mejor Solace o Elasticsearch? A ver, sinceramente, a mí personalmente me gusta más el Elasticsearch porque lo veo más moderno. Pero es que, sinceramente, es lo mismo. O sea, o lo mismo. Son dos tecnologías distintas, funcionan un poco distinto, pero lo que te solucionan es el mismo problema. Puedes usar igualmente Solace o Elasticsearch. Para tu proyecto va a ser más o menos indistinto. Aparte, en Drupal básicamente se usa como capa que te lo traduce todo, con lo cual a ti te es completamente transparente, o sea, no sabes lo que estás usando por detrás. Sabes que las consultas son una cosa externa que no es un MySQL de tu Drupal. Con eso ya tienes bastante. Como digo, a mí, mi caso, últimamente me llama más la atención usar Elasticsearch porque lo veo como más moderno y en algunos casos un poco más usable. Pero es que realmente en muchos otros proyectos se usa Solace y no hay ningún problema con ello. Es más, creo que en la comunidad de Drupal.org como Solace llevan bastantes más años trabajando con ello, ya venía de Drupal.Cyta y todo esto, creo que te va a ser más fácil encontrar soporte si es que tienes algún problema con Solace. Pero bueno, igualmente, al final te buscas por internet y en Elasticsearch también vas a encontrar gente que te pueda soporte. Bueno, he dicho todo esto. ¿Qué otras ventajas te permite tener un motor de búsqueda como Solace o Elasticsearch? O sea, usar Setjapi para tener un motor de búsqueda independiente de las tablas originales de Drupal, ¿qué otras ventajas tiene? Pues aquí viene usar facets. Facets es otro módulo contribuido en Drupal que te permite tener filtros facetados. ¿Qué son los filtros facetados? A ver, digamos que por ejemplo, hablando que antes teníamos Wallapop o Segunda Mano, cuando tú seleccionas que tienes la categoría Motor o Coches, no sé cómo lo llaman esta gente, en esa categoría Vehículos o Coches, cuando tienes esa categoría marcada te van a salir otros filtros que antes no habían, que pueden ser por ejemplo el número de kilómetros, si es cambio manual o cambio automático o si es diésel o gasolina. Estos filtros cuando se hacen en la categoría, yo qué sé, cocina, no te salen, o sea, solo tiene sentido que salgan esos filtros cuando se hacen en una categoría donde hay resultados que, bueno, pues tiene sentido que estos filtros se estén mostrando. Esos son facetados, ¿vale? Son filtros que dependen de los resultados de la búsqueda. Si por poner un ejemplo decimos que estamos en la categoría Coches y buscamos pos X nombre de marca de vehículo o modelo de vehículo, que es un modelo de vehículo de hace 30 años, ese modelo de vehículo no tiene cambio automático y tampoco hay diésel porque para esa época solo había gasolina y solo eran manuales, o para ese modelo en concreto solo es gasolina y manual. Los filtros ya no van a salir como que es automático, o sea, no te va a dar la opción a marcar el filtro automático y diésel. Los filtros que se pueden marcar son los que están disponibles en los resultados actualmente disponibles. No sé si me estoy explicando bien, pero al final este tipo de filtros facetados se usan muchísimo como digo, pues esto, por ejemplo, Wallapop, Segundo Mano, o Amazon mismo también lo tiene, o muchas otras webs, y en muchos e-commerce se tiene esto porque es muy recomendable. Implica que no tienes resultados de búsqueda donde sale, no hay resultados. Si todo lo que hay son filtros de búsqueda facetados, que son los típicos que salgan en la columna lateral que ponen ahí los facetados, es una forma de que el usuario esté navegando por tu web y haciendo click y descubriendo, ah, pues si cambio de categoría hombre o mujer o invierno o verano o lo que sea, voy viendo otros artículos pero nunca veo una página de aquí no hay resultados. Sinceramente, en muchos proyectos se pide el tema de facetados y en Drupal es bastante simple implementar esto, como digo, es activar el módulo search API y el módulo facets. Y si quieres que sea en base de datos MySQL, el search API con base de datos, y si no, pues es javis más solar o es javis más elasticsearch. Y poca cosa más, o sea básicamente, os quería comentar de que hacer este tipo de buscadores bastante personalizados, o sea, muy personalizados en muchos casos, en Drupal es relativamente simple. Haz de saber un poco del tema, busca algún vídeo o tutorial que te explique más o menos cómo funciona search API porque al final se ha de configurar, o sea, no es una cosa de activar y ya está. Has de activar y configurar qué campos quieres, después ir a la views porque al final ese search API hace que tengas que en las views puedas marcar que las consultas se hagan contra search API. O sea, al final estás usando la interfaz de views para generar los listados y estás usando la configuración que has puesto en search API para el tema de consultas a una cosa externa. Total, es muy potente, pero requiere bastante configuración, no es complicada, pero requiere unos mínimos conocimientos. Y nada más, creo que esto sirve como caso para la gente que dice que un Drupal no sirve para hacer cosas muy complejas donde tenga unas búsquedas muy complejas. Por ejemplo, una cosa que me ha pasado en más de un cliente, un cliente que tiene varias webs y quiere que desde todas ellas, que tienen un buscador propio, cuando buscas algo allí, aparte de mostrar los resultados, los contenidos de esa web, también te muestre los resultados de los contenidos de sus otras webs. Y que si haces clic te vayas a la web original donde estaba. Imagínate que tienes un e-commerce que vende productos y tienes un e-commerce para la parte de verano y un e-commerce para la parte de invierno. Si alguien busca botas de X, quiere que en el buscador le salgan los resultados de verano y los de invierno, que son dos webs independientes. Esto con Drupal y con search API se puede. Tienes un motor de búsqueda externo, que puede ser un solar, donde ahí indexas los contenidos de las dos webs, o sea, lo típico es imagen, título, texto y el link. Cuando se hace el usuario de la web y hace el filtrado, ve los resultados y al hacer clic, como el link apunta al dominio de la web, pues lo estás redirigiendo a la web donde está ese contenido. Es una forma de obtener contenidos cruzados en webs que todas son tuyas propias. Es otra cosa avanzada que también no es que se pida mucho, pero se pide. Entre comidas, bastante. Pero también, en Drupal es relativamente simple hacer esto. Y nada más. Y creo que en el siguiente episodio voy a hablar del módulo Flux, que hay gente que no sabe ni que existe ni para que sirve. Así que atentos a la siguiente semana. Chao.

¿Tienes algún proyecto en mente?

Si quieres hacer algo en Drupal tal vez puedas contratarme.

Ya sea para consultoría, desarrollo o mantenimiento de sitios web Drupal.