tutorial features descargar java lucene solr

java - features - solr tutorial



¿Cómo obtener rangos de facetas en resultados solr? (4)

Supongamos que tengo un campo llamado precio para los documentos en Solr y tengo ese campo facetado. Quiero obtener las facetas como rangos de valores (por ejemplo: 0-100, 100-500, 500-1000, etc.). ¿Cómo hacerlo?

Puedo especificar los rangos de antemano, pero también quiero saber si es posible calcular los rangos (por ejemplo, para 5 valores) automáticamente en función de los valores en los documentos.


Es posible que haya una mejor respuesta específica para Solr, pero trabajo con Lucene directo, y como no estás obteniendo mucha tracción voy a recibir una puñalada. Allí, crearía un Filter FilteredQuery con una consulta FilteredQuery envuelva la Query original. Luego obtendría un FieldCache para el campo de interés. Enumere los aciertos en el conjunto de bits del filtro, y para cada acierto, obtiene el valor del campo de la memoria caché de campo y lo agrega a SortedSet. Cuando tenga todos los hits, divida el tamaño del conjunto en el número de rangos que desee (de cinco a siete es un buen número de acuerdo con la interfaz de usuario chicos), y en lugar de una restricción de un solo valor, sus facetas ser una consulta de rango con los límites inferior y superior de cada uno de esos subconjuntos.

Recomiendo usar alguna lógica de casos especiales para una pequeña cantidad de valores; obviamente, si solo tiene cuatro valores distintos, no tiene sentido tratar de hacer 5 refinamientos de rango de ellos. Por debajo de un cierto umbral (digamos 3 * su número ideal de rangos), simplemente muestra las facetas normalmente en lugar de rangos.



He resuelto cómo calcular las facetas dinámicas sensibles para los rangos de precios de los productos. La solución implica un preprocesamiento de documentos y un procesamiento posterior de los resultados de la consulta, pero solo requiere una consulta a Solr, e incluso debería funcionar en la versión anterior de Solr como 1.4.

Redondee los precios antes del envío

Primero, antes de enviar el documento, redondee el precio al "límite redondeado de facetas redondo" más cercano y guárdelo en el campo "precio redondeado". A los usuarios les gustan sus facetas para que parezcan "250-500", no "247-483", y el redondeo también significa que recuperas cientos de facetas de precio, no millones de ellas. Con un poco de esfuerzo, el siguiente código se puede generalizar para redondear bien en cualquier escala de precios:

public static decimal RoundPrice(decimal price) { if (price < 25) return Math.Ceiling(price); else if (price < 100) return Math.Ceiling(price / 5) * 5; else if (price < 250) return Math.Ceiling(price / 10) * 10; else if (price < 1000) return Math.Ceiling(price / 25) * 25; else if (price < 2500) return Math.Ceiling(price / 100) * 100; else if (price < 10000) return Math.Ceiling(price / 250) * 250; else if (price < 25000) return Math.Ceiling(price / 1000) * 1000; else if (price < 100000) return Math.Ceiling(price / 2500) * 2500; else return Math.Ceiling(price / 5000) * 5000; }

Los precios permitidos van 1,2,3, ..., 24,25,30,35, ..., 95,100,110, ..., 240,250,275,300,325, ..., 975,1000 y así sucesivamente.

Obtenga todas las facetas en precios redondeados

En segundo lugar, al enviar la consulta, solicite todas las facetas en precios redondeados ordenados por precio: facet.field=rounded_price . Gracias al redondeo, obtendrás como máximo unos cientos de facetas.

Combina facetas adyacentes en facetas más grandes

En tercer lugar, después de que tengas los resultados, el usuario solo quiere ver de 3 a 7 facetas, no cientos de facetas. Por lo tanto, combine las facetas adyacentes en algunas facetas grandes (llamadas "segmentos") tratando de obtener una cantidad aproximadamente igual de documentos en cada segmento. El siguiente código bastante más complicado hace esto, devolviendo tuplas de (inicio, fin, recuento) adecuadas para realizar consultas de rango. Los recuentos devueltos serán correctos siempre que los precios se hayan redondeado al límite más cercano:

public static List<Tuple<string, string, int>> CombinePriceFacets(int nSegments, ICollection<KeyValuePair<string, int>> prices) { var ranges = new List<Tuple<string, string, int>>(); int productCount = prices.Sum(p => p.Value); int productsRemaining = productCount; if (nSegments < 2) return ranges; int segmentSize = productCount / nSegments; string start = "*"; string end = "0"; int count = 0; int totalCount = 0; int segmentIdx = 1; foreach (KeyValuePair<string, int> price in prices) { end = price.Key; count += price.Value; totalCount += price.Value; productsRemaining -= price.Value; if (totalCount >= segmentSize * segmentIdx) { ranges.Add(new Tuple<string, string, int>(start, end, count)); start = end; count = 0; segmentIdx += 1; } if (segmentIdx == nSegments) { ranges.Add(new Tuple<string, string, int>(start, "*", count + productsRemaining)); break; } } return ranges; }

Filtrar resultados por faceta seleccionada

En cuarto lugar, supongamos que ("250", "500", 38) fue uno de los segmentos resultantes. Si el usuario selecciona "$ 250 a $ 500" como filtro, simplemente haga una consulta de filtro fq=price:[250 TO 500]


Para responder a su primera pregunta, puede obtener rangos de facetas utilizando el soporte genérico de consulta de facetas. Aquí hay un ejemplo:

http://localhost:8983/solr/select?q=video&rows=0&facet=true&facet.query=price:[*+TO+500]&facet.query=price:[500+TO+*]

En cuanto a su segunda pregunta (que sugiere automáticamente intervalos de facetas), eso aún no se ha implementado. Algunos argumentan que este tipo de consultas se implementaría mejor en su aplicación en lugar de dejar que Solr "adivine" los mejores rangos de facetas.

Aquí hay algunas discusiones sobre el tema: