2009-12-04 20 views
14

Estoy tratando de implementar un Faceted search o etiquetar con filtrado de etiquetas múltiples. En la navegación con facetas, solo se muestran categorías no vacías y el número de elementos en la categoría que también coinciden con los criterios ya aplicados se presenta entre paréntesis.Implementación eficiente de búsqueda facetada en bases de datos relacionales

I can get all items having assigned categories using INNER JOINs y get number of items in all category using COUNT and GROUP BY, sin embargo, no estoy seguro de cómo se escalará a millones de objetos y miles de etiquetas. Especialmente el conteo.

sé que hay algunas soluciones no-relacionales como Lucene + SOLR, pero he encontrado también algunas implementaciones basadas en RDBMS de código cerrado que se dice que son entreprise-fuerza como el software FacetMap.com o Endeca, por lo que debe ser una forma eficiente de realizar búsquedas facetadas en bases de datos relacionales.

¿Alguien tiene experiencia en búsqueda facetada y podría dar algunos consejos?

¿Caché los recuentos para cada conjunto de categorías? ¿Tal vez usar alguna técnica incremental inteligente que actualice los contadores?

Editar:

Un ejemplo de navegación por facetas se puede encontrar aquí: Flamenco.

Actualmente tengo el esquema estándar de 3 tablas (elementos, etiquetas y etiquetas de elementos como se describe aquí: http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html#toxi) más una tabla para las facetas. Cada etiqueta tiene asignada una faceta.

+0

¿Se han establecido ya las tablas? ¿Puedes proporcionar la estructura? –

+0

Para aclarar, Endeca no es un contenedor en una base de datos relacional. Almacena toda la información necesaria para la búsqueda con facetas y otras operaciones internamente. –

+0

El enlace flamenco ya no funciona. ¿Es este el nuevo? http://flamenco.berkeley.edu/ –

Respuesta

4

Solo puedo confirmar lo que dice Nils. Los RDBMS no son buenos para la búsqueda multidimensional. He trabajado con algunas soluciones inteligentes, contadores de almacenamiento en caché, uso de activadores, etc. Pero al final, el indexador dedicado externo siempre gana.

QUIZÁS, si transforma sus datos en un modelo dimensional y lo alimenta a algún OLAP [me refiero al motor MDX], tendrá un buen rendimiento. Pero parece una solución demasiado pesada, y definitivamente NO será en tiempo real.

Por el contrario, la solución con motor de indexación dedicado (piense en Lucene, piense en Sphinx) se puede hacer casi en tiempo real con actualizaciones de índice incremental.

5

IMO, las bases de datos relacionales no son tan buenas en la búsqueda. Obtendrá un mejor rendimiento de un motor de búsqueda dedicado (como Solr/Lucene).

0

En cuanto a los recuentos, ¿por qué los extrae a través de SQL? Tendrás que repetir el resultado en el código de todos modos, ¿por qué no hacer tu conteo allí?

Actualmente estoy utilizando este enfoque en una aplicación de búsqueda facetada que estoy desarrollando y está funcionando bien. La única parte difícil es configurar su código para que no muestre la faceta hasta que llegue a una nueva faceta. En ese momento, muestre la faceta y el número de filas que encontró para ella.

Este enfoque supone que está retirando una lista de todos los elementos coincidentes, y por lo tanto, varias filas con la misma faceta. Cuando ordena este resultado por faceta, es fácil obtener el conteo en su código.

+2

Puede haber cientos de miles de registros coincidentes, así que no puedo almacenar el conjunto de resultados en la memoria. Estoy recuperando solo la primera página, pero quiero saber cuántos registros de todo el conjunto de resultados encajan en las categorías que se muestran en las facetas. –

2

Faceted Search es un problema analítico, lo que significa que el diseño dimensional es una buena apuesta. Aka, lo que buscas debe estar en forma de tabla.

Incluya todas las columnas de interés en su tabla analítica.

Ponga valores continuos en cubos.

Utilice columnas booleanas para "muchos" elementos como categorías o etiquetas, por ejemplo, si hay tres etiquetas "foo", "barra" y "baz", tendría tres columnas booleanas.

Utilice una vista materializada para crear su tabla analítica.

Indexe la mierda. Algunas bases de datos admiten índices para este tipo de aplicación.

Solo filtro una vez.

Unión de los resultados.

Cree vistas materializadas preagregadas para consultas comunes.

Este artículo puede ayudar a usted también: https://blog.jooq.org/2017/04/20/how-to-calculate-multiple-aggregate-functions-in-a-single-query/

with filtered as (
    select 
    * 
    from cars_analytic 
    where 
     [some search conditions] 
) 

--for each facet: 

select 
    'brand' as facet, 
    brand as value, 
    count(*) as count 
from 
    filtered 
group by 
    brand 

union 

select 
    'cool-tag' as facet, 
    'cool-tag'as value, 
    count(*) as count 
from 
    filtered 
where 
    cool_tag 

union 

... 


-- sort at the end 
order by 
    facet, 
    count desc, 
    value 

100.000 registros con 5 facetas de ~ 150 ms

Cuestiones relacionadas