Volltextsuche allg. Vorgehensweise - Wörter extrahieren - Regex?

14/08/2008 - 23:56 von Thomas Hübner | Report spam
Hi All,

ich starte gerade einen neuen Versuch eine Volltextsuche auf einer MDB
aufzusetzen. Nachdem das Thema in Der Datenbanken NG völlig OT gelaufen
ist und der Teil den ich jetzt angehen will nur zum Teil was mit der
Datenbank zu tun hat auf ein Neues. Bitte keine Diskussionen über die
Art der Datenbank und ob es Sinn macht das auf einer MDB zu realisieren.

Mein Plan (bis Pkt3. schon "codiert") sieht folgendermaßen aus:

Indizierung:
1. -> Memofeld wird per Regex von Sonderzeichen befreit und sàmmtliche
Leerzeichen auf ein einzelnes (zwischen zwei Worten) eingedampft.

Problem - ich erhalte zu viel "Müll" (der die das so zu einzelne Zahlen
aus Gliederungen usw.) Ich kann Zahlen nicht ganz eliminieren da diese
auch in Typenbezeichnungen vorkommen. AUch mit Unterstrichen habe ich
ein Problem, da diese von \W ignoriert werden und \_ nicht akzeptiert wird.

2. Memofeld wird in Array geladen split(CHR(" "))

funktioniert zufriedenstellend

3. Array wird in eine Datenbanktabelle (Dict - ID,WORD,REFERENCE)
gekippt. Dabei werden Doppelte Worte durch Exception auf indizierter
Spalte verworfen. (das ist dirty aber in diesen Mengen werden die Daten
nur einmal verarbeitet)

ich hatte durch den "Müll" in 1. ca. 450k Datensàtze was die DB
natürlich ganz schön aufblàht. Haltet Ihr Left 5 oder 8 und das
Datenbankfeld auf die gleiche Breite begrenzt für eine gute Idee?


4. Dict wird durchgangen und in REFERENCE (Memo) werden Kommasepariert
die ID's der Datensàtze zutreffenden hinterlegt

Das ist die einzige Lösung die mir dazu einfàllt da z.B. s.1. das Wort
"der|die|das" sogut wie in jedem Dokument vorkommt, indiziert wird und
somit 90% (1,8k) aller Dokumente ID's in dem Kommaseparierten String stehen

Betrieb:
1. Dict wird in eine Hashtable geladen (Key(WORD))

Ich halte das für idealer, da mittlerweile die Zielsysteme auf 2GB Ram
aufgerüstet sind und ich Netzwerktraffic (gibt es so nur noch beim Start
des Tools) einspare. Seht Ihr das auch so? Immerhin enthàlt die
Hashtable im Endzustand mit Sicherheit 200k Eintràge

2. bei Eingabe eines Wortes wird in Hashtable nachgeschlagen und die
Kommaseparierte Zeichenkette an ein command als Parameter übergeben (
WHERE IN (?)

3. Ergebnis wird dargestellt

Was haltet Ihr von dieser Vorgehensweise. Bis auf evtl. Regexhilfe zu
Pkt. 1. erwarte ich keine Codeschnipsel sondern eher grundsàtzliche
Vorschlàge zu dieser Vorgehensweise. Über die stàndige Wartung der Dict
table werde ich mir dann Spàter noch den Kopf zerbrechen. Für mich gilt
es jetzt erstmal zum Einstieg die 2k Memofelder _sinnvoll_ zu indizieren

Danke für Euer Interesse,
Gruß,
Thomas
 

Lesen sie die antworten

#1 Peter Fleischer
15/08/2008 - 07:57 | Warnen spam
"Thomas Hübner" schrieb im Newsbeitrag
news:g829mn$1pj$

ich starte gerade einen neuen Versuch eine Volltextsuche auf einer MDB
aufzusetzen. Nachdem das Thema in Der Datenbanken NG völlig OT gelaufen
ist und der Teil den ich jetzt angehen will nur zum Teil was mit der
Datenbank zu tun hat auf ein Neues. Bitte keine Diskussionen über die Art
der Datenbank und ob es Sinn macht das auf einer MDB zu realisieren.



Hi Thomas,
wenn ein Lebensmüder von einer Brücke springen will zwingt sich zwangslàufig
die Frage auf, warum er das machen will. Eine kleine Erklàrung zum zu
realisierenden Ziel wàre hilfreich.

Mein Plan (bis Pkt3. schon "codiert") sieht folgendermaßen aus:

Indizierung:
1. -> Memofeld wird per Regex von Sonderzeichen befreit und sàmmtliche
Leerzeichen auf ein einzelnes (zwischen zwei Worten) eingedampft.

Problem - ich erhalte zu viel "Müll" (der die das so zu einzelne Zahlen
aus Gliederungen usw.) Ich kann Zahlen nicht ganz eliminieren da diese
auch in Typenbezeichnungen vorkommen. AUch mit Unterstrichen habe ich ein
Problem, da diese von \W ignoriert werden und \_ nicht akzeptiert wird.



Ich kann mir nicht vorstellen, dass nach Zahlen mit vorausgehendem
Leerzeichen gescuht werden soll.

2. Memofeld wird in Array geladen split(CHR(" "))

funktioniert zufriedenstellend

3. Array wird in eine Datenbanktabelle (Dict - ID,WORD,REFERENCE) gekippt.
Dabei werden Doppelte Worte durch Exception auf indizierter Spalte
verworfen. (das ist dirty aber in diesen Mengen werden die Daten nur
einmal verarbeitet)



Programmablaufsteuerung mittels Exception ist ein totale Bremse und sollte
vermieden werden. Besser ist eine Contains-Abfrage in Form z.B. "SELECT
count(ID) FROM Dict WHERE Word = ?".

Unklar ist, was REFERENCE bedeutet. Heißt das, dass es für jedes Wort
mehrere Eintràge geben kann? Wenn das so ist, dann sollte normalisiert
werden.

ich hatte durch den "Müll" in 1. ca. 450k Datensàtze was die DB natürlich
ganz schön aufblàht. Haltet Ihr Left 5 oder 8 und das Datenbankfeld auf
die gleiche Breite begrenzt für eine gute Idee?



Was heißt "Left 5 oder 8"?

4. Dict wird durchgangen und in REFERENCE (Memo) werden Kommasepariert die
ID's der Datensàtze zutreffenden hinterlegt



Das bedeutet, dass die ID's als Zeichenketten abegelgt werden und damit den
Speicherbedarf unnötig aufblàhen.

Das ist die einzige Lösung die mir dazu einfàllt da z.B. s.1. das Wort
"der|die|das" sogut wie in jedem Dokument vorkommt, indiziert wird und
somit 90% (1,8k) aller Dokumente ID's in dem Kommaseparierten String
stehen



Wie wàre es, Artikel und Pràpositionen auszuschließen?

Betrieb:
1. Dict wird in eine Hashtable geladen (Key(WORD))

Ich halte das für idealer, da mittlerweile die Zielsysteme auf 2GB Ram
aufgerüstet sind und ich Netzwerktraffic (gibt es so nur noch beim Start
des Tools) einspare. Seht Ihr das auch so? Immerhin enthàlt die Hashtable
im Endzustand mit Sicherheit 200k Eintràge



Warum alles laden und nicht nur die Eintràge, die gebraucht werden?

2. bei Eingabe eines Wortes wird in Hashtable nachgeschlagen und die
Kommaseparierte Zeichenkette an ein command als Parameter übergeben (
WHERE IN (?)



Bei einer normalisierten DB wàre eine Abfrage mit JOIN völlig ausreichend
und auch viel schneller.

3. Ergebnis wird dargestellt

Was haltet Ihr von dieser Vorgehensweise.



Ohne die genaue Aufagnestellung zu kennen, ist es schwer, diese Technolgie
zu beurteilen. Ich finde sie nicht besonders gut.

Bis auf evtl. Regexhilfe zu Pkt. 1. erwarte ich keine Codeschnipsel
sondern eher grundsàtzliche Vorschlàge zu dieser Vorgehensweise.



Dazu braucht man aber erst einmal eine genaue Zielstellung, da das Thema
recht komplex ist und schon kleine Abweichungen u.U. total andere
Algorithmen favorisieren können.

Über die stàndige Wartung der Dict table werde ich mir dann Spàter noch
den Kopf zerbrechen.



Aber genau das ist wesentlich, da ohne aktuellen Index auch nichts gefunden
wird.

Für mich gilt es jetzt erstmal zum Einstieg die 2k Memofelder _sinnvoll_
zu indizieren



Jedenfalls ist eine Zeichenkette (auch noch als Memo-Feld) mit den Satz-ID's
die denkbar ungünstigste Variante, es sei, dafür gibt es gewichtige Gründe.

Viele Grüsse
Peter

Ähnliche fragen