2009-12-04 16 views
14

Ich versuche, eine Faceted search oder Markierung mit multiplen Tag-Filter zu implementieren. In der facettierten Navigation werden nur nicht leere Kategorien angezeigt und die Anzahl der Elemente in der Kategorie, die auch bereits angewendete Kriterien erfüllen, wird in Klammern dargestellt.Effiziente Implementierung der facettierten Suche in relationalen Datenbanken

I can get all items having assigned categories using INNER JOINs und get number of items in all category using COUNT and GROUP BY, aber ich bin mir nicht sicher, wie es auf Millionen von Objekten und Tausenden von Tags skalieren wird. Vor allem das Zählen.

Ich weiß, dass es einige nicht-relationalen Lösungen wie Lucene + SOLR, aber ich habe auch einige Closed-Source-RDBMS-basierte Implementierungen gefunden entreprise-Stärke wie FacetMap.com oder Endeca Software sollen sein, so muss es eine sein Effiziente Art, Facettensuche in relationalen Datenbanken durchzuführen.

Hat jemand Erfahrung in facettierter Suche und könnte ein paar Tipps geben?

Cache die Zählungen für jede Kategorie Set? Vielleicht eine intelligente inkrementelle Technik verwenden, die die Zähler aktualisiert?

Edit:

Ein Beispiel für facettierte Navigation finden Sie hier: Flamenco.

Derzeit habe ich das Standard-3-Tabellen-Schema (Elemente, Tags und Items_Tags wie hier beschrieben: http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html#toxi) plus eine Tabelle für Facetten. Jedem Tag wurde eine Facette zugewiesen.

+0

Haben Sie Tabellen bereits eingerichtet? Können Sie die Struktur bereitstellen? –

+0

Um zu verdeutlichen, ist Endeca kein Wrapper in einer relationalen Datenbank. Es speichert intern alle Informationen, die für die facettierte Suche und andere Operationen benötigt werden. –

+0

Flamenco-Link funktioniert nicht mehr. Ist das das Neue? http://flamenco.berkeley.edu/ –

Antwort

4

Ich kann nur bestätigen, was Nils sagt. RDBMS sind nicht gut für mehrdimensionale Suche. Ich habe mit einigen cleveren Lösungen gearbeitet, Counter zwischengespeichert, Trigger verwendet und so weiter. Aber am Ende gewinnt immer ein externer dedizierter Indexer.

VIELLEICHT, wenn Sie Ihre Daten in dimensionale Modell umwandeln und es zu etwas OLAP [ich meine MDX-Engine] füttern - es wird gut funktionieren. Aber es scheint ein bisschen zu schwere Lösung, und es wird definitiv NICHT in Echtzeit sein.

Im Gegenteil, Lösung mit dedizierter Indexing-Engine (Think Lucene, denke Sphinx) kann in Echtzeit mit inkrementellen Index-Updates gemacht werden.

5

IMO, relationale Datenbanken sind nicht so gut in der Suche. Sie würden bessere Leistung von einer dedizierten Suchmaschine (wie Solr/Lucene) bekommen.

0

In Bezug auf die Zählungen, warum ziehen sie über SQL? Sie müssen die Ergebnismenge in Ihrem Code trotzdem durchlaufen, also warum zählen Sie nicht dort?

Ich verwende diesen Ansatz derzeit in einer Facettensuche App, die ich entwickle und es funktioniert gut. Der einzige knifflige Teil besteht darin, den Code so einzurichten, dass die Facette erst ausgegeben wird, wenn sie eine neue Facette erreicht. Geben Sie zu diesem Zeitpunkt die Facette und die Anzahl der Zeilen aus, die Sie dafür gefunden haben.

Bei diesem Ansatz wird davon ausgegangen, dass Sie eine Liste aller übereinstimmenden Elemente und somit mehrerer Zeilen mit derselben Facette zurückziehen. Wenn Sie dieses Ergebnis per Facette bestellen, ist es einfach, die Anzahl in Ihrem Code zu ermitteln.

+2

Es kann Hunderttausende von übereinstimmenden Datensätzen geben, so dass ich die Ergebnismenge nicht im Speicher speichern kann. Ich erhalte nur die erste Seite, aber ich möchte wissen, wie viele Datensätze von der gesamten Ergebnismenge in Kategorien passen, die unter Facetten angezeigt werden. –

2

Die facettierte Suche ist ein analytisches Problem, was bedeutet, dass dimensionales Design eine gute Wahl ist. Aka, die Sache, gegen die Sie suchen, muss tabellarisch sein.

Schließen Sie alle relevanten Spalten in Ihre Analysetabelle ein.

Kontinuierliche Werte in Buckets eingeben.

Verwenden Sie boolesche Spalten für "viele" Elemente wie Kategorien oder Tags. Beispiel: Wenn drei Tags "foo", "bar" und "baz" vorhanden sind, hätten Sie drei boolesche Spalten.

Verwenden Sie eine materialisierte Ansicht, um Ihre Analysetabelle zu erstellen.

Index den Mist aus ihm heraus. Einige Datenbanken unterstützen Indizes für diesen Anwendungstyp.

Nur einmal filtern.

Verbinden Sie Ihre Ergebnisse.

Erstellen Sie voraggregierte materialisierte Ansichten für allgemeine Abfragen.

Dieser Artikel könnte Sie auch helfen: 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 Datensätze mit 5 Facetten in ~ 150 ms

Verwandte Themen