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

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.

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.

  • http://wiki.apache.org/solr/Solrj


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

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad

Información básica acerca de la protección de datos

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

Software Architect 👷‍♀️ | Tech Leader 🚀 | Senior Developer: Backend 🧩 and occasionally in Frontend 🖼️ | DevSecOps 🛠️ | Banking 🏛️ | Digital Transformation Agent 🎯 | Problem Solver (Mr. Wolf) 🐺

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

10/06/2025

Iván Suarez Romero

Aprende cómo migrar tu sitio Joomla 3 a Joomla 5 de forma segura, manteniendo el diseño, la funcionalidad y compatibilidad con extensiones. Una guía paso a paso con recomendaciones, imágenes y buenas prácticas para actualizar sin sorpresas.

04/06/2025

Gonzalo Matarrubia González

Descubre qué es Yocto Project, sus ventajas, usos reales en Izertis y cómo crear tu propia distribución Linux para Raspberry Pi paso a paso, de forma sencilla y flexible.

30/05/2025

Roberto José

¿Trabajas con Drupal y SonarQube 9.9? En este artículo exploramos cómo adaptar el análisis estático para evitar falsos positivos, desactivar reglas conflictivas del Quality Profile y delegar el estilo a PHP CodeSniffer. Una guía práctica para mejorar la integración sin depender aún de SonarQube 10.