kOorj: logische Verbindungen! bloss wie?

hi,

ich hab mir mal so ne kleine Suche gebastelt und die würde ich jetzt liebend gerne um ein feature erweitern. Und zwar soll der user seine suchstrings kombinieren können, ganz a la Google + co. mit "AND", "OR", "+", "-", etc. Nur wie geht das bitte möglichst ohne schier endlose Verschachtelungen von wegen if(preg_matach[...]) oder so. Google half mir ledier nicht weiter, da ich gar nicht richtig weiß wonach ich suchen soll.

thx 4 help
kOorj

  1. moin.

    ich hab mir mal so ne kleine Suche gebastelt und die würde ich jetzt liebend gerne um ein feature erweitern. Und zwar soll der user seine suchstrings kombinieren können, ganz a la Google + co. mit "AND", "OR", "+", "-", etc. Nur wie geht das bitte möglichst ohne schier endlose Verschachtelungen von wegen if(preg_matach[...]) oder so. Google half mir ledier nicht weiter, da ich gar nicht richtig weiß wonach ich suchen soll.

    Falls Du das mit PERL machen möchtest, da gibts das Modul Text::Query (Suchen wie in Altavista).

    Gruss, Rolf

    1. naja nein das ganze soll eine volltextsuche über PHP/MySQL sein, trotzdem thx

      1. Halihallo kOorj

        naja nein das ganze soll eine volltextsuche über PHP/MySQL sein, trotzdem thx

        Lass mal hören, wieviele kb/mb und Datensätze du durchsuchen
        möchtest und welche Operatoren du genau unterstützt haben möchtest.
        Ggf. liesse sich auch eine einfach umzusetzende Lösung finden, die
        halbwegs betriebstaugliche Geschwindigkeiten bringt...

        Viele Grüsse

        Philipp

  2. Halihallo kOorj

    ich hab mir mal so ne kleine Suche gebastelt und die würde ich jetzt liebend gerne um ein feature erweitern. Und zwar soll der user seine suchstrings kombinieren können, ganz a la Google + co. mit "AND", "OR", "+", "-", etc. Nur wie geht das bitte möglichst ohne schier endlose Verschachtelungen von wegen if(preg_matach[...]) oder so. Google half mir ledier nicht weiter, da ich gar nicht richtig weiß wonach ich suchen soll.

    Vorab: Das sind logische Operatoren und diese werden von Google nicht
    unterstützt. Zudem hat if (preg_match()) mehr mit PHP denn einer Datenbank zu tun.

    1. Frage: Was willst du nun? - Alles über PHP, oder über die
       Datenbank umsetzen?

    1.1 Falls letzteres: Welche Datenbank steht dir zur Verfügung?
           Aha, MySQL wie ich eben gesehen habe. Fulltext-Index!
           Glaube mir, es selber (gut) umzusetzen ist kein Kinderspiel...

    2. Einfach wird das nicht... Eine Bool'sche Suche zu implementieren
       ist nicht einfach, sogar sehr schwer, wenn sie auch in kurzer
       Zeit ( => gute Performance) Ergebnisse ausspucken soll.

    Es gibt mehrere Möglichkeiten eine derartige Suche umzusetzen, aber
    zuerst will ich eine Antwort von dir hören, bis ich mir die Finger
    wund tippe :-)

    Kurz vorab:
    http://dev.mysql.com/doc/mysql/en/Fulltext_Boolean.html
        MySQL bietet dies von Haus aus, PostgreSQL IMHO auch.

    Viele Grüsse

    Philipp

  3. Hallo,

    ich kann nur sagen: basteln. Man kann sich die Abfragen ja in PHP zusammenstellen, wie man will. Hab ich auch gemacht. Meine letzte Suche war auch mit Fulltext (ist übrigens Scheisse) und das sucht ja erstmal mit ODER - naja in den Versionen vor 4 halt. Da muß man sich schon die Wörter alle einzeln rauspicken und in die Abfrage wieder einsetzen.

    Wo ist genau Dein Problem, was hast Du versucht?

    Gruß, Andreas

    --
    <img src="http://was-ist-das.andreas-lindig.de/was_ist_das_fetzen.jpg" border="0" alt="">
    hier könnte auch ruhig mal'n neues Bild stehen.
  4. Moin,

    ich hab mir mal so ne kleine Suche gebastelt und die würde ich jetzt liebend gerne um ein feature erweitern. Und zwar soll der user seine suchstrings kombinieren können, ganz a la Google + co. mit "AND", "OR", "+", "-", etc. Nur wie geht das bitte möglichst ohne schier endlose Verschachtelungen von wegen if(preg_matach[...]) oder so. Google half mir ledier nicht weiter, da ich gar nicht richtig weiß wonach ich suchen soll.

    Zunächst mal brauchst du einen Parser der dir deine Suchanfrage in appetitliche Happen zerlegt. In deinem Fall gibt es wohl zwei Arten von Happen: Suchwörter/-strings und Operatoren. Wie man das im Allgemeinen tut habe ich in </archiv/2004/7/84947/#m498922> beschrieben, hier in diesem speziellen Fall sollte es wohl auch ein Regex tun welcher nach AND/OR/+/- sowie Leerzeichen sucht und alles andere einfach so übernimmt.

    Wenn du den Teil fertig hast sollte er in der Lage sein aus einer Eingabe wie
      ich +suche OR jetzt -nach AND was tollem
    etwas wie
      String: ich
      Operator: AND
      String: suche
      Operator: OR
      String: jetzt
      Operator: NOT
      String: nach
      Operator: AND
      String: was
      String: tollem
    (zum Beispiel als Array) zu machen. Jetzt musst du zwischen Wörtern zwischen denen kein Operator steht irgendeinen Standardoperator, vermutlich AND, einfügen.

    Das formst du nun in eine MySQL-Abfrage um: Die Strings werden zu "foo LIKE '%string%'", die Operatoren übernimmst du einfach so. (Fast; "AND" und "OR" können so bleiben, bei "NOT" musst du aufpassen: Wenn das NOT am Anfang steht oder direkt nach einem OR kann es so bleiben, sonst muss noch ein AND davor.) Die Teilstücke werden dann einfach hintereinander geklebt:

    foo LIKE '%ich%' AND foo LIKE '%suche%' OR foo LIKE '%jetzt%' AND NOT foo LIKE '%nach%' AND foo LIKE '%was%' AND foo LIKE '%tollem%'

    Fertig ist deine Where-Bedingung. (In Wirklichkeit willst du natürlich den Volltextindex statt LIKE '%... benutzen.) Als Verbesserung bietet sich an, auch Anführungszeichen zu interpretieren und alles darin eingeschlossene als String zu betrachten. Bestimmt willst du auch die Syntax der Abfrage prüfen ("foo AND OR bar" gibt nicht so viel Sinn) und geeignete Maßnahmen treffen.

    Wenn du Klammerungen erlauben willst, kannst du die auf genau die gleiche Weise in die MySQL-Abfrage übernehmen, da ist nur die Prüfung auf korrekte Syntax etwas schwerer. (Da könnte fast das oben verlinkte Posting notwendig sein.)

    --
    Henryk Plötz
    Grüße aus Berlin
    ~~~~~~~~ Un-CDs, nein danke! http://www.heise.de/ct/cd-register/ ~~~~~~~~
    ~~ Help Microsoft fight software piracy: Give Linux to a friend today! ~~
  5. Hello,

    Da kannst Du ein nettes Suchwerkzeug aufbauen. Bau Dir ein Grid

    Feldselektor  Operatorselektor  Wert  Operatorselektor  Wert  Operatorselektor  Wert
             Operatorselektor (default=AND)
      Feldselektor  Operatorselektor  Wert  Operatorselektor  Wert  Operatorselektor  Wert
             Operatorselektor (default=AND)
      Feldselektor  Operatorselektor  Wert  Operatorselektor  Wert  Operatorselektor  Wert
             Operatorselektor (default=AND)
      Feldselektor  Operatorselektor  Wert  Operatorselektor  Wert  Operatorselektor  Wert
             ...
      ...

    Die Felder kannst Du aus der DB auslesen und dann je nach Typ, die Opetaoren anbieten.
    Wenn es praxisgerecht sein soll, dann benötigt man immer drei Operatoren pro Zeile:
      Feld größer Wert1 und kleiner Wert2 und like %Wert3%

    Like wird z.B. in drei Selektoren zerlegt:
    beginnt mit     Wert%
    endet mit       %Wert
    enthält         %Wert%

    In der Waagerechten werden die Filter ummer verundet
    In der Senkrechten kann man mittels JavaScript immer automatisch Zeilen hinzufügen und zwischen AND und OR wählen

    Man kann damit nicht alles erschlagen, aber es trifft die meisten Fälle und ist enorm bequem.
    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
  6. Also erstmal dankeschön an alle für eure ausführungen. So in etwa wie Henryk es beschrieben hat, dachte ich es mir auch nur wollte ich so etwas eigentlich umgehen.

    Nun erstmal genauer zu meinem Sachverhalt:

    Ich habe 2 Datenbanken (Rubriken, Partner) und beide haben eine beträchtliche Größe (2MB und 3MB). Die RubrikenDB besteht nur aus ID, Name, Clicks. Die PartnerDB enthält neben dem Namen und der Rubriken.ID doch ein paar mehr Informationen, wie zB Anschrift, etc.

    Nun soll es dem User möglich sein sowohl über die RubrikenDB Partner (mit der entsprechenden Rubrik) sowie direkt die Partner nach Namen zu suchen. So weit so gut, klappt auch alles:

    $q = mysql_query("SELECT * FROM Rubriken WHERE name LIKE '%".$_GET['qry']."%' ORDER BY name ASC");

    while($rub = mysql_fetch_assoc($qry))
     {
     $i++;
     $sub = mysql_query("SELECT * FROM Partner WHERE rub LIKE '%".$rub['ID']."|%'");
     if(mysql_num_rows($sub) != 0) $data[$i] = $rub['ID'];
     }

    foreach($data as $key=>$val)
     {
     $res = mysql_fetch_assoc($_mysql->qry("SELECT * FROM Rubriken WHERE id='".$val."'"));
     $name = @eregi_replace('('.preg_quote($_GET['qry']).')', "<b>\1</b>", $res['name']);
     echo $name;
     }

    So in etwa sieht die Suche nach Rubriken aus. Ganz Simpel. Die SUche nach Name dementsprechend noch einfacher. Nun kann ich mich eigentlich bloß nicht entscheiden, ob ich die Variante von Henryk nutze oder es mal hiermit versuche:
    http://dev.mysql.com/doc/mysql/en/Fulltext_Boolean.html

    bye