[PHP/MySQL] highlighting bei suchergebnissen

crishnak

Active member
ID: 218350
L
2 Juli 2006
31
5
hi,
ich hab auf meiner homepage eine suchmaschine mithilfe von php und mysql geschrieben.
dabei sollen bewertungen von büchern via titel oder autor des buches gesucht und gefunden werden...damit man möglichst viel spielraum bei der suche hat habe ich

SELECT * FROM ... WHERE ... LIKE '%$suchwort%'

verwendet. (damit zum beispiel beim suchbegriff "korea" auch ein buch mit dem titel "koreanische geschichte" gefunden wird)
dummerweise würde dieser titel auch bei einer suche nach "rea" gefunden werden. für dieses problem hab ich leider keine lösung gefunden. um die ganze sache dennoch etwas übersichtlicher zu gestalten, möchte ich, dass das gesuchte wort in den ergebnissen hervorgehoben wird(andere farbe, unterstrichen...sowas in der art). meine frage ist, ob das möglich ist oder ob man das problem mit den "überschüssigen" ergebissen lösen kann.

mfg
 
Zuletzt bearbeitet:
hervorheben ist kein problem... in etwas so:
PHP:
$der_titel_des_buches = preg_relpace("~($suchbegriff)~i","<span style='color:red;'>\\1</span>",$der_titel_des_buches);

das zweitere ist schon mehr ein problem... woher soll der computer wissen das koreanische was mit korea zu tun hat, aber rea nix mit korea? das ganze ist ein hochkomplexes thema... es gibt firmen die bieten derartige suchlösungen an, aber die sind teuer und funktionieren auch nicht unbedingt hunderporzent.
 
Schonmal mit der mysql volltextsuche probiert? Ich habe jetzt meine erstens Erfahrungen damit gemacht und muss sagen "Joar" kann sich schon mehr sehen lassen, also diese LIKE %% Dinger. Das einzige was mir bei deiner Situation noch einfällt suche mit regex in der DB anstatt mit LIKE und definiere unter Umständen sogar noch ne mindestlänge. (Was aber auch wieder nach hinten losgehen kann)
 
Schonmal mit der mysql volltextsuche probiert? Ich habe jetzt meine erstens Erfahrungen damit gemacht und muss sagen "Joar" kann sich schon mehr sehen lassen, also diese LIKE %% Dinger. Das einzige was mir bei deiner Situation noch einfällt suche mit regex in der DB anstatt mit LIKE und definiere unter Umständen sogar noch ne mindestlänge. (Was aber auch wieder nach hinten losgehen kann)

volltextsuche ist so ne sache... die funktioniert für solche sachen wie produkt bezeichnungen äussert eingeschränkt. da diese nur auf kompletten wörtern basiert... also würdest du jetzt nach "korea" suchen, würdest du nicht das buch "koreanische geschichte" finden. sondern nur bücher die "korea" als wort beinhalten.
 
Doch würde man mit der erweiterung WITH QUERY EXPANSION, aber es kann wie gesagt auch voll strainge Ergenbinsse liefern.

*edit
zumindest mit meinen bissherigen Erfahrungen, das war allerdings auch ein Wörterbuch mit Latein vokabeln da isses vielleicht wieder anders


*edit 2
schmarrn hast recht :roll:

 
Zuletzt bearbeitet:
danke erstmal soweit...ich denk mal, dass highlighting krieg ich hin.
da wär dann noch eine sache: bis jetzt sortiere ich meine ergebnisse nach alphabet...besser wäre es allerdings wenn die besten treffer weiter oben stehen. da vielleicht noch einen tipp? :biggrin:

zeroccc, so ganz komm ich mit deinen variablenersatz nicht klar...hab schon ne weile nichts mehr mit php gemacht. könnteste mir den code an meine version anpassen. hier mal ein auszug:
//anfrage
$anfrage = "SELECT * FROM buchverzeichnis WHERE autor LIKE '%$suchwort%' ORDER by autor";
if ($ergebnis = mysql_query($anfrage)) {echo"Ihre Suchergebnisse:<br><br>";} else {echo"error:" . mysql_error;}
$treffer = (mysql_num_rows($ergebnis));
while($ausgeben = mysql_fetch_object($ergebnis)) {
echo "<table border='1' width='100%'>";
$user = ("$ausgeben->user");
$titel = ("$ausgeben->titel");
$autor = ("$ausgeben->autor");
$bewertung = ("$ausgeben->bewertung");
$text = ("$ausgeben->text");
echo "<tr>";
echo "<td>";
echo "<font face='Verdana' size='2'>Bewertung von: </font>";
echo "<font face='Verdana' size='2'>$user</font>"; echo"<BR>";
echo "<font face='Verdana' size='2'><b>\"$titel\" von:</b><br></font>";
echo "<font face='Verdana' size='2'>$autor</font>"; echo"<BR><br>";
echo "<font face='Verdana' size='2'>$bewertung Punkte <BR><br></font>";
echo "<font face='Verdana' size='2'>$text<BR><br><br></font>";
echo "</td>";
echo "</tr>";
echo "</table>";

//holen und ausgeben
echo "<b>Die Suche nach \"$suchwort\" ergab insgesamt: $treffer Treffer.</b>";

so, ein letzter edit: ich hatte nen syntaxfehler übersehen, das highlighting funzt. ideen zur optimierung der trefferliste?
 
Zuletzt bearbeitet:
es soll nicht preg_relpace sonder preg_replace heißen.

und die funktion einfach auf die variable anwenden in der die syntax hervorgehoben werden soll.

bei dir also wahrscheinlich der titel.

jperl
 
das
PHP:
$titel = ("$ausgeben->titel");
gegen das ersetzen
PHP:
$titel = preg_relpace("~($suchwort)~i","<span style='color:red;'>\\1</span>",$ausgeben->titel);

ich hoffe mal dass das nur ne interne anwendung ist... ansonsten sicherheit :shifty:

ne sortierung nach relevanz ist auch schon wieder so nen thema... wie soll das script die relevanz beurteilen? sponntan würde ich da mal sagen man macht ne art einfaches scoring auf der basis von vorkommnissen und an welchen stellen. zb für jedes vorkommnis vergibt man 1nen punkt... wenn ein wort mit dem suchbegriff anfängt oder endet vergibt man nochmals 1nen punkt, oder nen halben. wenn ein wort den suchbregiff 1:1 entspricht nochmal nen punkt. das müsste man durch testen dann ausbalancieren... ist eigentlich relativ leicht umzusezten. wie gut oder wie schlecht das funktioniert ist ne andere frag... hab das in der art noch nie getestet.

@strolch WITH QUERY EXPANSION ist was anderes... hast du ja schon selbst festgestellt. diese funktion ist in meinen augen aber absolut sinnlos... damit hollt man sich derartig viele sinnlose ergebnisse, dass das so nicht zu gebrauchen ist.
 
das mit dem scoring klingt gar nicht schlecht aber wie? wems noch nicht aufgefallen ist: bin kein profi...

zum thema sicherheit: naajaaaa...dazu sag ich lieber nichts, bzw. siehe oben.

wo liegt das größere sicherheitsproblem: das der code ist wie er ist oder das er hier frei einsehbar ist?
 
Zuletzt bearbeitet:
das mit dem scoring klingt gar nicht schlecht aber wie? wems noch nicht aufgefallen ist: bin kein profi...

zum thema sicherheit: naajaaaa...dazu sag ich lieber nichts, bzw. siehe oben.

wo liegt das größere sicherheitsproblem: das der code ist wie er ist oder das er hier frei einsehbar ist?

Frei einsehbar währe etwas anderes, auch wenn der jetzige für manch einen ein graus ist! ;)
 
:( was will man machen. ich hatte großes vor und nur knapp 2 monate zeit mich in html, php und mysql soweit einzuarbeiten, um meine idee umzusetzen. für schönes coding, blieb da nicht viel zeit. ahnung hatte ich gar keine und auch jetzt noch wenig. php für dummies hat mir das nötigste beigebracht weil ich auch keine anprechpartner in meinem bekanntenkreis hab. dann kam noch ein wenig seo hinzu und demnächst überarbeite ich das ganze wc3 konform...soll ja angeblich auch ganz nützlich sein, wenn es um suchmaschinenlistings geht.

und jetzt bin ich größtenteils mit contenterstellung beschäftigt um mehr besucher anzulocken.
da gibts an allen ecken genug arbeit und als freizeitprojekt, fehlt mir die zeit alles sofort sauber zu machen...leider.:roll:
 
das mit dem scoring klingt gar nicht schlecht aber wie? wems noch nicht aufgefallen ist: bin kein profi...

zum thema sicherheit: naajaaaa...dazu sag ich lieber nichts, bzw. siehe oben.

wo liegt das größere sicherheitsproblem: das der code ist wie er ist oder das er hier frei einsehbar ist?

wie... hrm. du leist das resultat in einen array ein. dabei tust du auch gleich das besagt scoring auf den titel anwenden, was du als extra feld in dem neuen array speicherst. dann tust du mit array sort das ganze nach dem scoring sortieren und gibts den array aus... ganz einfach wie du siehst ;)

sicherheit in dem sinn von SQL-Injektions und XSS
und dann haste auch noch nen paar sehr eigenartige konstrukte in deinem code. zb
PHP:
$text = ("$ausgeben->text");
wasn das?
PHP:
$text = $ausgeben->text;
reicht. und andere kleinigkeiten...
 
Anzumerken ist vielleicht noch, dass Regex für so einfache Ersetzungen zu ineffizient und auch nicht dafür gedacht sind. Ein einfaches str_replace (bzw. str_ireplace) tut es in deinem Falle auch.
 
Das hatte ich mir auch schon überlegt, aber nach kurzem Überlegen ist es an dieser Stelle doch gar nicht so unangebracht, da str_replace() sich ja im Gegensatz zu MySQL um die Gross/Kleinschreibung schert und str_ireplace() erst in PHP5 verfügbar ist, was längst noch nicht so weit verbreitet ist, wie man's gern hätte.
 
naja wenn du wirklich W3C konformen html code erzeugen willst solltest du erstmal alle deine tags schließen. auch die zeilenumbrüche.

gewöhn dir einfach gleich an <br /> zu schreiben. dann hast du später weniger probleme.

noch zur logik deines scripts.
wenn du mit deiner resource die mysql_query liefert weiterarbeitest wie z.Bsp. mysql_num_rows, bringt sich das ja nur wenn wirklich was zurückgegeben wurde.
also solltest dus wenn dann in die if anweisung reinschreiben, da du ansonsten anstatt von einer fehlermeldung mehrere hast.

jperl
 
wie... hrm. du leist das resultat in einen array ein. dabei tust du auch gleich das besagt scoring auf den titel anwenden, was du als extra feld in dem neuen array speicherst. dann tust du mit array sort das ganze nach dem scoring sortieren und gibts den array aus... ganz einfach wie du siehst
ich denke mal ich werd mich erstmal wieder in die materie einarbeiten müssen, bis ich das wieder als einfach empfinde. ;) aber danke für die erläuterung.

PHP:
$text = ("$ausgeben->text");
wasn das?
PHP:
$text = $ausgeben->text;

dieses stück code ist eine beinahe 1 zu 1 übernahme aus php für dummis...dort gabs eine routine, mit der ich auch meine ausgabe realisiert hab...von daher stammt der syntax nicht von mir und mein server hat auch keine probleme beim interpretieren angezeigt, von daher war mir nicht unbedingt ein fehler bewusst.
 
Anzumerken ist vielleicht noch, dass Regex für so einfache Ersetzungen zu ineffizient und auch nicht dafür gedacht sind. Ein einfaches str_replace (bzw. str_ireplace) tut es in deinem Falle auch.

das preg_replace ist mit voller absicht gewählt... weil so bleibt die groß und klein schreibung erhalten. da hilft dir kein str_replace und auch kein str_ireplace...

mal nen ganz einfachs beispiel... jemand such nach "auto", ein titel in der datenbank heißt Autobahn. was passiert jetzt... str_replace macht gar nix und str_ireplace macht dir aus der Autobahn ne autobahn. oder wenn jemand nach "Bahn" sucht würde zb aus ner Strassenbahn mit str_replace gar nix werden und mit str_ireplace ne StrassenBahn.
 
Man darf natürlich nicht den Suchbegriff als Replacement wählen.
Aber du hast recht, mit den Boardmitteln ist dieses Problem nur unbefriedigend lösbar. Wirklich schade, dass man bei solch trivial anmutenden Ersetzungen bereits zu preg_replace greifen muß, aber wenn man sich selbst ein str_replace mit backreferences zusammenschustert ist der Performancegewinn auch wieder flöten...
 
so...weil das so super geklappt hat, hab ich noch einen:biggrin:
die suchergebnisse werden bis jetzt einfach nur unter einander weg gelistet. man kann sich vorstellen, dass bei vielen treffern die liste ziemlich lang ist. von daher würd ich das gern auf mehrere seiten verteilen (ähnlich google und co). also müsste ich das auslesen aus meiner datenbank unterbrechen, das programm müßte sich merken wo es aufhört und dort weiter machen, wenn man die nächste seite aufruft. ideen?