apache-solr

Apache Solr es una plataforma de búsquedas basada en Apache Lucene, que funciona como un "servidor de búsquedas". Sus principales características incluyen búsquedas de texto completo, resaltado de resultados, clustering dinámico, y manejo de documentos ricos (como Word y PDF). Solr es escalable, permitiendo realizar búsquedas distribuidas y replicación de índices, y actualmente se está usando en muchos de los sitios más grandes de Internet.

La principal característica de Solr (o al menos la más útil) es su API estilo REST, ya que en vez de usar drivers o APIs programáticas para comunicarnos con Solr podemos hacer peticiones HTTP y obtener resultados en XML o JSON. (por cierto, por si tienen curiosidad, se pronuncia "Solar" y no es un acrónimo).

Solr no expone una interfaz REST "perfecta" (que use todos los principios de HTTP 1.1), pero los datos tienen una representación simple que viaja entre el cliente y el servidor, sin ninguna encapsulación rara con SOAP u otras pesadillas. Además, los XML son legibles por personas, y JSON se puede usar para consumir con JavaScript y realizar pruebas.

Las ventajas de usar esta interfaz universal (y no propia de un lenguage) son varias:

  • es agnótico del lenguaje porque usa XML y JSON, que hoy en día pueden ser interpretados por casi cualquier cosa. La métrica generalmente es JavaScript: si podemos interpretarlo con JavaScript dentro de todas las limitaciones que impone un navegador, entonces lo podemos interpretar en cualquier otro lugar. Por supuesto, JavaScript tiene soporte nativo para JSON y XML.
  • es agnóstico de los tipos de datos, ya que HTTP sólo transmite textos. Los lenguajes dinámicos como PHP tienen éxito porque su protocolo básico no tiene tipos estrictos. Si la presentación lo va a mostrar por pantalla, ¿por qué no debería alcanzar con un string?
  • más o menos es un protocolo estándar (aunque la representación de datos no lo sea): si alguien inventa una base de datos y publica sus propio protocolo binario de comunicación, tendríamos muchas más librerías.

Solr está escrito en Java, pero lo podemos usar con nuestro lenguaje preferido, simplemente usando las peticiones GET para realizar búsquedas en el índice, y POST para agregar documentos.

Por supuesto suele haber una librería para cada lenguaje de programación que encapsula la interfaz REST, pero es muy simple construir una librería con, por ejemplo, JavaScript, e igualmente no es obligatorio usarla. Todo esto nos lleva a otro punto: si Solr tuviera una interfaz binaria como MySQL, ¿cómo podríamos invocarla desde JavaScript? HTTP es universal ya que hoy en día hasta casi un secador de pelo puede hacer invocaciones HTTP.

Una pequeña prueba

A diferencia de Lucene, Solr es muy facil de configurar y comenzar a utilizar.

Como la interfaz principal de Solr es web, necesita un contenedor de servlets. Solr tiene varios servlets que exponen distintos servicios, como /update o /select.

Para empezar, lo único que necesitamos es descomprimir la última versión de Solr, ir al directorio example/ y ejecutar el comando:

java -jar start.jar

Esto inicia el servidor de Solr con un esquema de documentos de ejemplo. Ya estamos listos para agregar documentos y ejecutar consultas!

Creando una prueba JUnit

Vamos a usar la librería Java para insertar un documento y realizar una búsqueda. Este API en realidad es un wrapper de la interfaz HTTP, y nos permite acceder a Solr muy facilmente desde Java. Hay que recordar que esta misma funcionalidad la podríamos realizar con peticiones HTTP directas al servidor.

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
 
 
public class SolrTest {
 
    /* Esta es la URL donde se encuentra levantado el servidor de Solr. */
    private static final String URL = "http://localhost:8983/solr";
    private CommonsHttpSolrServer server;
 
    /** Lo primero es establecer la conexión al servidor, representada
        por el objeto CommonsHttpSolrServer.
    */
    @Before
    public void before() throws MalformedURLException {
        server = new CommonsHttpSolrServer(URL);
        server.setParser(new XMLResponseParser());
    }
 
 
    /** Al terminar la prueba vamos a borrar todos los registos, para tener un
      * índice limpio la próxima vez que corramos la prueba.
     */
    @After
    public void after() throws SolrServerException, IOException {
        server.deleteByQuery("*:*");
    }
 
    /** Esta prueba ingresa un documento, lo busca, y por último borra todo el contenido
        del índice para dejar todo limpio para la próxima vez.
     */
    @Test
    public void buscar() throws MalformedURLException, SolrServerException, IOException {
 
        //creamos un documento de Solr para insertar. 
        //los campos están definidos en Solr, y no podemos usar campos no definidos. 
        SolrInputDocument doc1 = new SolrInputDocument();
        doc1.addField("id", "123", 1.0f);
        doc1.addField("name", "un documento de prueba", 1.0f);
        Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
        docs.add(doc1);
        server.add(docs);
        server.commit();
 
        //buscamos el documento.
        //la sintaxis básica de búsqueda es "campo:texto". En este caso, estamos
        //buscando la palabra "prueba" en el campo "name". 
        //Si quisieramos buscar todos los documentos, pondriamos "*:*"
        SolrQuery query = new SolrQuery();
        query.setQuery("name:prueba");
        QueryResponse rsp = server.query(query);
        SolrDocumentList docList = rsp.getResults();
 
        assertTrue(docList.size() == 1);
        assertEquals("123", docList.get(0).get("id"));        
    }
}
 

Con qué seguir

Esta fue sólo una muy pequeña introducción al uso de Solr. En la documentación de Solr pueden empezar a darse cuenta de las capacidades de este motor de búsquedas, como la replicación de índices (para lograr alta disponibilidad y escalar facilmente) o el sharding de contenido (un índice distribuido, con partes viviendo en distintos servidores pero accedidos como si fueran una única instancia).

Otra cosa para probar es AJAX Solr, una librería JavaScript que accede directamente a Solr para realizar consultas y poder crear interfaces ricas de forma muy rápida.

Basado en Getting to know Solr, por Giorgio Sironi.
    • Anima13

      Hola, Tengo un problema con solr. Quiero hacer querys insensibles pero no consigo hacerlo. <br />Configure solr pero consigo querys sensibles, por ejemplo (titulo: Esto*) + (titulo: *esto*) Alguna sugerencia para hacer querys insensibles? Gracias por adelantado.

    • mtoe

      Estimado, estoy tratando de implementar apache solr pero se me torna engorroso y no consigo indexar la base de datos, podrias ayudarme? [quote name="Anima13"]Hola, Tengo un problema con solr. Quiero hacer querys insensibles pero no consigo hacerlo. <br />Configure solr pero consigo querys sensibles, por ejemplo (titulo: Esto*) + (titulo: *esto*) Alguna sugerencia para hacer querys insensibles? Gracias por adelantado.[/quote]

    • eyanina

      Hola tienes algun ejemplo que funcione sobre base de datos por favor? Gracias ilike_panama@yahoo.com

    • elFilipino

      El test unitario esta mal:

      SolrQuery query = new SolrQuery();
      query.setQuery("name:prueba");
      QueryResponse rsp = server.query(query);
      SolrDocumentList docList = rsp.getResults();

      assertTrue(docList.size() == 1);
      assertEquals("un documento de prueba", docList.get(0).get("id"));

      Cambien assert final por:

      assertEquals("123", docList.get(0).get("name"));

    • elFilipino

      El test unitario esta mal:

      SolrQuery query = new SolrQuery();
      query.setQuery("name:prueba");
      QueryResponse rsp = server.query(query);
      SolrDocumentList docList = rsp.getResults();

      assertTrue(docList.size() == 1);
      assertEquals("123", docList.get(0).get("id"));

      Cambien assert final por:

      assertEquals("un documento de prueba", docList.get(0).get("name"));

    Deja tus comentarios

    Post comment as a guest

    0

    Seguinos en Facebook.

    Publicá tus artículos.

    Publicar Convertite en redactor para Dos Ideas y compartí tus conocimientos a una comunidad que sigue creciendo!
    Quiero publicar

    Los Comentarios.

    invitado
    hasta ahora no sabia que era el cinismo pero ahora que lo se me he dado cuenta porque he tenido tant...
    Dai
    Es broma?
    busquen el significado de cinismo.
    esta el antiguo significado y el moderno,
    el moderno...
    Yan
    Hola:
    Unas duda, Drools ¿tiene una interfaz gráfica para poder generar y editar reglas? o todo se t...
    Maxi
    Gracias por la info, esta bien explicado y funciono como solución a mi problema que tenia con el mét...
    jonybuzz
    Cierto. Y más desafiante: Qué pasa si dejamos ir algo que sí funciona? Algo que sentimos que puede m...

    Inspiración.

    "Si tú tienes una manzana y yo tengo una manzana e intercambiamos las manzanas, entonces tanto tú como yo seguiremos teniendo una manzana cada uno. Pero si tú tienes una idea y yo tengo una idea, e intercambiamos las ideas, entonces ambos tendremos dos ideas"

    Bernard Shaw