Categorías del Tutorial

icono_twiter
Jose Manuel Sánchez Suárez

Consultor tecnológico de desarrollo de proyectos informáticos.

Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación

Somos expertos en Java/J2EE

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2011-05-04

Tutorial visitado 5.635 veces Descargar en PDF
Búsquedas "facetadas" en Solr con el soporte de Solrj.

Búsquedas "facetadas" en Solr con el soporte de Solrj.


0. Índice de contenidos.


1. Introducción

Después de la introducción a Apache Solr, y de ver el soporte de solrj para indexar y recuperar documentos desde java, en este tutorial vamos a estudiar cómo recuperar metainformación asociada a los resultados de una consulta.

Las facetas para Solr son subcojuntos de información asociados a los resultados de una consulta que nos permiten agrupar los mismos por distintos campos de los documentos.

El ejemplo más típico es el de la búsqueda de productos en el que además, recuperamos información sobre cuántos de esos productos pertenecen a cada una de las categorías de productos existentes. De este modo podremos después afinar la búsqueda de productos, restringiendo los resultados a los productos asociados a dichas categorías.

Sin el soporte de Solr es lo que, contra una base de datos relacional, tendríamos que hacer con un group by y un count(*).

En Solr, se puede realizar esta operativa en una única consulta, de modo que el resultado de la búsqueda nos devuelva dicha información adicional, sobre el contenido de la misma.

Además, a partir de la versión 3.1 de Solr, podemos indicar en la consulta que las facetas las cree por rangos, de modo que podríamos recuperar los productos facetados por rangos de precio.


2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 17' (2.93 GHz Intel Core 2 Duo, 4GB DDR3 SDRAM).
  • Sistema Operativo: Mac OS X Snow Leopard 10.6.7
  • Apache Solr 3.1.
  • Eclipse Helios SR2 con m2eclipse
  • Junit 4.8.2

3. Búsqueda de productos facetados a categorías.

Añadir una faceta a una consulta es tan simple como invocar a los siguientes métodos:

	query.setFacet(true);
	query.addFacetField("cat");

Primero indicamos que queremos hacer uso de facetas y después el o los campos por los que queremos agrupar esa metainformación, en el ejemplo por el campo categoría de producto.

El resultado de una consulta facetada se puede leer de la siguiente forma:

	@Test
	public void retrieveCategoryFacetedResult() throws SolrServerException{
		final SolrQuery query = new SolrQuery(); 
		query.setQuery("name:ipod");
		query.setFacet(true);
		query.addFacetField("cat");

		final QueryResponse response = server.query(query);
		
        final FacetField categoryFacet = response.getFacetField("cat");

        assertFaceted(categoryFacet, "electronics",0,3);
        assertFaceted(categoryFacet, "camera",3,0);
        
	}

	private void assertFaceted(FacetField facet, String name, int categoryPositionInFacet, int productsInCategory) {
        Assert.assertEquals(name,facet.getValues().get(categoryPositionInFacet).getName());
        Assert.assertEquals(productsInCategory,facet.getValues().get(categoryPositionInFacet).getCount());
		
	}

Con ello, lo que conseguimos es poder añadir la siguiente información al resultado de las búsquedas, de modo que el usuario pueda restringir la misma en función a subconjuntos.



4. Búsqueda de productos facetados por rango de precios.

Si quisieramos añadir rangos a una faceta, por ejemplo para recuperar productos en función a un rango de precios, podríamos hacer algo como lo que sigue:

	@Test
	public void retrievePriceFacetedResult() throws SolrServerException{
		final SolrQuery query = new SolrQuery(); 

		query.setQuery("name:ipod");
		query.setFacet(true);
		
		query.add("facet.range","price");
		query.add("f.price.facet.range.start","0");
		query.add("f.price.facet.range.gap","100");
		query.add("f.price.facet.range.end","1000");
		
		final QueryResponse response = server.query(query);
		// response.getFacetDates() TODO: no existe un getFacetRanges ¿?
        NamedList counts = (NamedList) ((SimpleOrderedMap) 
        					((SimpleOrderedMap) ((SimpleOrderedMap) 
        							response.getResponse().get("facet_counts")).get("facet_ranges")).get("price")).get("counts");
        
        Assert.assertEquals(2, counts.get("0.0"));
        Assert.assertEquals(1, counts.get("300.0"));
	}

A comentar:

  • facet.range: asigna el campo a facetar por rango,
  • f.price.facet.range.start: permite establecer el valor mínimo de precio a facetar,
  • f.price.facet.range.end: permite establecer el precio máximo a facetar,
  • f.price.facet.range.gap: establece el salto entre cada uno de los rangos de la faceta
  • llama la atención que no exista un método directo, o al menos yo no lo he encontrado, para recuperar la faceta por rango. Si bien, sí existe para las fechas (getFacetDates()) no existe un método análogo en el api de solrj para recuperar las facetas por rango, de ahí la necesidad de recuperarlo manualmente del contenido de la respuesta conociendo las claves de los mapas.

5. Referencias.


6. Conclusiones.

Aunque parece que el api de java aún no está preparado para soportar todo lo que si podemos hacer con xml o json, seguimos avanzando en el sorprendente mundo de Solr ;).

Un saludo.

Jose

jmsanchez@autentia.com

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL: