Se ha hablado mucho sobre Apache Solr. Pasado el impedimento inicial de su instalación y configuración para la integración con Drupal nos encontramos con un nuevo buscador mejorado y mucho más flexible que el buscador por defecto de Drupal. El objetivo de este post no es alabar las bonanzas de Apache Solr ni los motivos por los que usarlo si no la manera en la que podemos personalizar su funcionamiento.
Una de las características principales de Apache Solr es la búsqueda facetada. Aunque la búsqueda facetada ya lleva un tiempo con nosotros a través del módulo search (del core) en combinación con Faceted Search este buscador nos permite llegar a una integración y un control sobre la indexación del contenido muy interesante en términos de interfaz de usuario. Por defecto Apache Solr nos permite la búsqueda de nodos y de usuarios e indexa los campos por defecto de los tipos de contenido de Drupal, aunque permite (mediante interfaz gràfica de usuario) añadir los campos CCK que tengamos disponibles para cada tipo de nodo. También nos permite activar y desactivar la indexación de tipos de nodos, de manera que los resultados que encontremos sean sólo los relevantes. Adicionalmente nos proporciona una serie de bloques que implementa la funcionalidad de la búsqueda facetada con ordenación a través de diferentes criterios y filtrado a través de taxonomía, fecha de creación, autor, ...
El problema surge cuando quieres ordenar o filtrar por un criterio que no viene contemplado por Apache Solr. Por partes.
Filtrado
Imaginemos que tenemos un tipo de contenido al que le hemos añadido un campo CCK con un campo de texto. Como ejemplo usaremos un tipo de contenido coche al que le hemos añadido un campo para representar el tipo de carburante que utiliza (gasolina, diesel, híbrido, eléctrico, ...), sería lógico pensar en introducir un filtro de búsqueda para que el usuario pudiera restringir la búsqueda a los coches que usan un carburante concreto. Para conseguir esto nos vamos a servir del módulo Apache Solr Facet Builder, que nos va a proporcionar la posibilidad de añadir casi cualquier filtro que queramos a nuestras búsquedas. Vale la pena decir que a día de hoy este módulo se encuentra todavía en desarrollo, por lo que las funcionalidades y la interfaz pueden variar sustancialmente en el momento de la lectura de este post.
Una vez instalado el módulo la intuición nos lleva a buscar la página de configuración de Apache Solr Facet Builder, lo cual nos daremos cuenta rápidamente que es un error porque no existe tal página. Lo que hace Apache Solr Facet Builder es añadir un nuevo tipo de display en Views.

A partir de ahí deberemos seguir los siguientes pasos para cada filtro que queramos establecer:
- Crear una nueva vista. En nuestro ejemplo del tipo nodo.
- En el display default configuramos los aspectos básicos de nuestra búsqueda. Sin aplicar ninguno de los filtros que queremos mostrar en nuestra búsqueda facetada aún.
- En este punto tenemos una búsqueda que nos proporciona el conjunto total de resultados que queremos mostrar cuando ningún filtro está activo. Para cada filtro (gasolina, diesel, ...) crearemos un nuevo display del tipo Faceted. Es importante el nombre y el título que le demos al display, ya que será el texto que aparecerá en la opción del filtro una vez lo activemos. En la imagen del ejemplo se ha creado un display para que filtre segun los criterios de default y un campo cck que debe ser 0. El segundo display es el complementario a éste.


En este punto tenemos una vista con todos los displays que queramos, aunque los que nos interesan son los del tipo Faceted. Ahora nos podemos dirigir a
admin/settings/apachesolr/enabled-filters
y veremos una nueva sección de filtros a activar llamada Apache Solr Facet Builder :-) Aparecerá un nuevo filtro por cada una de las vistas que hayamos creado con este método. Ojo! Una vista equivale a un filtro. Un display en esa vista equivale a una opción del filtro.
Orden
Para ordenar los resultados según el criterio que creamos más conveniente el proceso es completamente diferente. A día de hoy no he sido capaz de encontrar un módulo que facilite el trabajo o que de alguna facilidad más allá de la prevista por el módulo Apache Solr. Eso no quiere decir que cuando estés leyendo esto no haya aparecido uno que haga que este método quede obsoleto.
Para ilustrar lo que queremos hacer pondré otro ejemplo diferente. Imaginemos que queremos ordenar los resultados de la búsqueda con apache Solr en función del valor de los votos de los usuarios de un tipo de contenido Blog. A nivel práctico parece claro que la mejor opción para tener contenido valorable por los usuarios es usar el módulo Voting API con, por ejemplo, un Fivestar.
Para hacer esto hay un requisito previo, uno de esos que siempre obviamos pero que esta vez tendremos que hacer, leer el README.txt del módulo Apache Solr. En este documento encontraremos lo siguiente:
Exposed Hooks in 6.x:
...
hook_apachesolr_prepare_query(&$query, &$params, $caller);
This is pretty much the same as hook_apachesolr_modify_query() but runs earlier
and before the query is statically cached. It can e.g. be used to add
available sorts to the query.
Example:
function my_module_apachesolr_prepare_query(&$query) {
// Add a sort on the node ID.
$query->set_available_sort('nid', array(
'title' => t('Node ID'),
'default' => 'asc',
));
}
...
hook_apachesolr_update_index(&$document, $node)
Allows a module to change the contents of the $document object before it is sent to the Solr Server.
To add a new field to the document, you should generally use one of the pre-defined dynamic fields.
Follow the naming conventions for the type of data being added based on the schema.xml file.
...
hook_apachesolr_sort_links_alter(&$sort_links)
Called by the sort link block code. Allows other modules to modify, add or remove sorts.Para poder ordenar los resultados según un criterio antes que nada ese criterio debería estar reflejado de alguna manera en los índices de búsqueda de Apache Solr. Para hacer esto deberemos implementar en un módulo hook_apachesolr_update_index. Con esto lo que conseguiremos es añadir un nuevo campo en el índice. Debemos tener en cuenta que (según la documentación que se puede encontrar en el fichero schema.xml) deberemos indicarle el tipo del valor que estamos añadiendo (entero, booleano, cadena de texto, ...) utilizando los prefijos que se indican en ese fichero. Nuestro ejemplo es un claro ejemplo de entero multivalor (integer multivalue equivale al prefijo 'im_').
Para nuestro ejemplo:
function custom_sort_apachesolr_update_index(&$document, $node) { // Only act if the table will be present if (module_exists('voting_api')) { // Add a voting sort // 1. First we need to get the votes value $query = "SELECT value FROM {votingapi_cache} WHERE function = 'average' AND content_id = %d"; $rating = db_result(db_query($query, $node->nid)); // 2. If downloads cannot be found default to 0. Otherwise if it has not been voted yet won't be searchable. $rating = $rating ? $rating : 0; // 3. Add an integer multivalue (im_*) for this node. $document->setMultiValue('im_custom_sort_rating', $rating); } }
Cuando reindexemos el contenido tendremos una nueva columna llamada im_custom_sort_rating con los valores de los votos en el momento de la indexación.
Hemos terminado la fase en la que modificamos los valores del servidor solr. Vamos a lidiar con la interfaz de usuario para que se muestren los controles de ordenación. Tal y como sugiere la documentación de más arriba, tendremos que implementar hook_apachesolr_prepare_query.
/** * Implementation of hook_apachesolr_prepare_query */ function custom_sort_apachesolr_prepare_query(&$query) { // Add a sort on the node ID. $query->set_available_sort('im_custom_sort_rating', array( // Texto que aparecerá en la UI 'title' => t('Votes'), // Orden por defecto 'default' => 'desc', )); }
Una vez hecho esto si vamos a la página de búsqueda (previo reindexado del contenido) veremos aparecer nuestro nuevo criterio de ordenación entre los posibles. Si no nos gusta el lugar donde aparece de la lista (podemos querer que tenga más visibilidad) implementaremos un último hook en nuestro módulo custom_sort.
/** * Implementation of hook_apachesolr_sort_links_alter */ function custom_sort_apachesolr_sort_links_alter(&$sort_links) { // $sort_links is passed by reference. $sorted_keys = array( 'score', // This means relevancy 'im_custom_sort_rating', 'im_custom_sort_otro_criterio', 'im_custom_sort_otro_criterio_mas', 'created', ); foreach ($sorted_keys as $key) { $new_sort_links[$key] = $sort_links[$key]; } $sort_links = $new_sort_links; }
Esto es todo. Que no es poco, pero que no es tanto. Espero poder ahorraros un tiempo en vuestros desarrollos con el fantástico Apache Solr (al final sí me he mojado para dar mi opinión xD). Ya sabeis como funciona esto, si teneis dudas teneis los comentarios.
La foto de la cabecera del post es de gavinbell, gracias por compartir en CC.






Después de leer el articulo parece que apache soir es un módulo de drupal, ¿No?. Aunque creo que se puede instalar en otro cms.
El nombre me confunde porque apache soir me suena servidor web apache. ¿no tiene nada que ver? ¿Es módulo de apache? ¿Es una librería php independiente para ser utilizada en php?
Me parece que es un programa php que lo que hace es recorrer nuestra web y poder hacer búsquedas llamando a ciertas funciones.
Es decir, lo que me interesa puedo hacer un buscador interno para mi generador de test online. Porque estoy usando el buscador de google. Cómo google quiere quitar el búscador que estoy usando en mi web. Dónde puedo elegir si buscar en mi web o internet.
Sería muy pesado programar un buscador interno porque tendría que buscar en todos los campos. Y no es lo mismo porque puede encontrar una palabra en la pregunta y otra en una respuesta. Creo que se complica demasiado el select de mysql.
Apache Solr es un proyecto separado de Drupal. Drupal proporciona unos módulos para interccionar con el buscador. Esto es:
Espero que te sirva.