2009-04-08 15 views
0

Sagen wir, ich habe eine Vorname> MiddleName> LastName Hierarchie (~ 10k Reihen, wegen der Frage). Das heißt, Sie könnten "John> Mary-Anne> Eddy" oder "Eddy> John> Jacob" -Reihe haben. Der Punkt ist, dass die Hierarchie wenig Sinn macht und dem Benutzer sehr fremd ist (anders als beispielsweise ein Land> Staat> Stadtstruktur).Effiziente Suche in einer 3-Level-Hierarchie

Weil es so unstrukturiert und verwirrt ist, möchte ich dem Benutzer ein Auto-Complete-Eingabefeld zur Verfügung stellen. Während sie tippen, sollte sie nach möglichen Teilstring-Übereinstimmungen suchen, und wenn sie ihre Suchzeichenfolge auf einer Ebene "rooten", wird sie die Ergebnisse dann auf diese Ebene beschränken.

Nun, da gibt es viele Leute den Namen "John", macht es wenig Sinn, wenn sie geben "John" sie nur Ergebnisse zurück wie

  • John> Allen> Alexander
  • John> Alle> Burschawitz
  • John> Alle ... wiederholen 100mal ...

Weil sie nie die einzigartige Reihe "Jason> John> Smith" sehen.

Stattdessen sollten sie wieder so etwas wie ("*" ist nur ein beliebiger Indikator für den Benutzer von "hey, viel mehr Zeilen unterhalb dieser exist"):

  • John> Allen> *
  • Jason> John> Smith
  • Mike> John> *
  • Mary> Elena> Johnason

Wenn sie geben "John> Al" dann würden die Ergebnisse sein beschränkt auf etwas unter "John>", sollte aber ähnlich wie oben gruppiert werden.

Ich hoffe, die Erklärung ist klar. Die Anforderungen sind ein bisschen locker. Nur vernünftige, damit eine Person durch den Baum suchen und finden kann, wonach sie suchen.

Im Moment habe ich einige interessante SQL, die nach dem Suchbegriff in der Zeile sucht, seine Position, einige substring'ing, Gruppenbys und order by's, um die obigen Ergebnisse zu erhalten, aber es funktioniert nicht gut genug.

Ich versuche, dieses Problem auf einem typischen LAMP-Stack (außer mit Oracle) zu lösen. Es ist kein Shared Hosting, also habe ich volle Kontrolle über den Server. Die Daten ändern sich alle paar Wochen in kleine Mengen, und die Suchergebnisse können für einen angemessenen Zeitraum veraltet bleiben (z. B. ist ein Cron, der den Suchindex aktualisiert, nicht ausgeschlossen).

+0

Ich muss sagen, ich kann nicht verstehen, was Sie genau zu tun versuchen. Ich weiß nicht, ob Sie klarer sein können. – 108

+0

naja ... vielleicht eine bessere Analogie: Wenn Sie eine Liste von URLs hätten und nach "com" suchen, würden Sie nicht domain.com/a, domain.com/b, domain.com/b; Du würdest nur "domain.com/" wollen. das Ergebnis danach könnte "other.org/COMputers" sein –

+0

... und der Grund, warum Sie domain.com/a,/b,/c nicht wollen, ist, dass es so viele von ihnen gibt, dass andere Ergebnisse gedrängt werden so weit unten, dass sie nicht in den Top 10 Ergebnissen auftauchen würden. –

Antwort

0

Argh. Leider konnte ich mein Problem nicht beschreiben. Wie auch immer, hier ist die Lösung, die ich mir ausgedacht habe.

Erstellen Sie im Grunde eine zweite Tabelle aus der 3-spaltigen Tabelle, die alle eindeutigen Werte für jede nachfolgende Ebene der Hierarchie enthält, sowie eine Spalte, um die Tiefe dieser Zeile in der Hierarchie anzugeben.

z.Von mytable(A, B, C), search_t(A, B, C, level)

Also, mit "One> Two> Three" erstellen, erstellen Sie drei Reihen (A, B, C, Stufe):

  • "One", null, null, 1
  • "One", "Two", null, 2
  • "One", "Two", "Three", 3

Bei der Suche können Sie die Ebene einschränken, indem Sie einen Wert für Ebene kommissioniert und Bereitstellen von Werten für die oberen Spalten:

WHERE A='One' and level > 1 and (B like '%t%' or C like '%t')

Es kann ein wenig vereinfacht und generisch sein, wenn Sie eine search_str Spalte erstellen und die LIKE Abgleich mit, dass statt durchführen.

WHERE A='One' and level > 1 and search_str like '%t%'

Im Nachhinein wäre dies wahrscheinlich deutlicher gewesen, wenn die Daten bereits waren in einem adjacency-Liste Modell.