MySQL: Eintrag suchen, der die größte Übereinstimmung hat?
Sven
- datenbank
Hallo zusammen,
gibt es eine Möglichkeit mit MySQL so suchen zu lassen, dass ich den Eintrag erhalte, der mit dem Such-String die größtmögliche Übereinstimmung hat?
Beispielsweise stehen in der Tabelle 2 Einträge:
Pfannkuchen
Nudelholz
Und ich suche nach 'Pfanne' - dann sollte er mir Pfannkuchen rausschmeißen *g*
Klingt blöd - ist auch blöd. Aber vielleicht gibts da ne Möglichkeit?
Vielen Dank!
Lg
Sven
Klingt blöd - ist auch blöd. Aber vielleicht gibts da ne Möglichkeit?
ich erweitere deine liste mal:
pfannkuchen
pfannenstiel
annegreth
nudelholz
feld like '%pfanne%' wird dir da leider auch nicht helfen
dir bleibt nur übrigen den suchbegriff zu zerteilen, shingles nennen sich diese dinger - also satz oder wortbestandteile
sprich aus pfanne suchbegriff machst trennst du alle möglichen substrings raus, die aus 3 zeichen bestehen
pfa fan ann nne
feld like '%pfanne%'
wenn das keine ergebnisse liefert, dann nimmst du die wortteile:
feld like '%pfa%'
feld like '%fan%'
feld like '%ann%'
feld like '%nne%'
damit hast du eine 100%ig übereinstimmung bei pfannenstiel, 3 treffer bei pfannkuchen und 2 bei annegreth
sprich aus pfanne suchbegriff machst trennst du alle möglichen substrings raus, die aus 3 zeichen bestehen
pfa fan ann nne
feld like '%pfanne%'
wenn das keine ergebnisse liefert, dann nimmst du die wortteile:feld like '%pfa%'
feld like '%fan%'
feld like '%ann%'
feld like '%nne%'damit hast du eine 100%ig übereinstimmung bei pfannenstiel, 3 treffer bei pfannkuchen und 2 bei annegreth
Hey, vielen Dank, das klingt schonmal ziemlich genial. Hab auch soweit meine Funktion gemacht, die mir die Strings unterteilt, nur bei der Abfrage bin ich mir jetzt nicht sicher:
Muss ich da für jeden Fall eine Abfrage starten, oder lässt sich das kombinieren? Falls ich in deinem Beispiel 4 Abfragen benötige, muss es doch eine Möglichkeit geben, die miteinander zu vergleichen, oder?
Lg
Sven
Muss ich da für jeden Fall eine Abfrage starten, oder lässt sich das kombinieren? Falls ich in deinem Beispiel 4 Abfragen benötige, muss es doch eine Möglichkeit geben, die miteinander zu vergleichen, oder?
abfragen zusammenfügen tust du mit UNION
Hallo,
abfragen zusammenfügen tust du mit UNION
Ja, das habe ich auch so gemacht... wobei ich die jetzt zum testen einfach hintereinander geschrieben habe:
(SELECT name
FROM test
.test
WHERE name
LIKE '%pfa%')
UNION
(SELECT name
FROM test
.test
WHERE name
LIKE '%fan%')
UNION
(SELECT name
FROM test
.test
WHERE name
LIKE '%ann%')
UNION
(SELECT name
FROM test
.test
WHERE name
LIKE '%nne%')
ORDER BY name
Aber es muss doch eine Möglichkeit geben, die Suchtreffer dann zu sortieren? Aus der Ergebnistabelle geht ja nicht hervor, welcher Eintrag nun die meisten Treffer hatte...?
Lg
Sven
Hallo,
ich habs geschafft - die Funktion tut das, was sie tun soll. Aber das sind seeehr viele Schleifen... ich kopiere mal den Code hier rein, vielleicht mag ihn ja mal jemand überfliegen. Falls das zu verwirrend ist, und niemand Lust hat, sich das anzusehen, kann ich das voll verstehen - ich bin sicher, es geht auch einfacher.
Vielleicht hat ja jemand eine Optimierungsidee?
Lg
Sven
if($_POST['search']) {
$search_string = strip_tags($_POST['search']);
// Länge des Strings ermitteln, wenn nötig auf 20 Zeichen begrenzen
$search_len = strlen($search_string);
if($search_len > 20) { $search_len = 20; }
// Prüfen ob Suchstring zu kurz
if($search_len < 3) {
$error[] = $error_tooshort;
}
// Nur weitermachen, falls keine Fehler vorliegen
if(count($error) == 0)
{
// String in Abschnitte unterteilen und in $search_substr[] speichern
for($i=0; $i < $search_len; $i++)
{
if(strlen(substr($search_string,$i,3)) >= 3)
{
$search_substr[] = substr($search_string,$i,3);
}
}
// UNION-Abfrage erzeugen
$sql = "";
for($i=0; $i<count($search_substr); $i++)
{
$sql .= "(SELECT name
FROM datenbank
.test
WHERE name
LIKE '%".$search_substr[$i]."%')";
if($i < count($search_substr)-1) {
$sql .= " UNION ";
} else {
$sql .= " LIMIT 10";
}
}
// Abfrage durchführen: Für jeden Eintrag in der
// Datenbank wird geprüft, welche Teilstrings
// in den Eintrag hinein passen
$result = mysql_query($sql);
$num = mysql_num_rows($result);
if($num > 0)
{
while($row = mysql_fetch_array($result))
{
$j = 0;
for($i=0; $i<count($search_substr); $i++)
{
if(substr_count($row['name'],$search_substr[$i]) > 0)
{
$j++;
}
}
// In diesem zweidimensionalen Array werden
// gespeichert: Die Anzahl der Treffer und
// der dazugehörige Datenbank-Eintrag
$search_res[] = array($j,$row['name']);
}
} else
{
$error[] = $error_noresults;
}
// Array sortieren
rsort($search_res);
// Array ausgeben
for($i=0; $i<count($search_res); $i++)
{
for($j=0; $j<count($search_res[$i]); $j++)
{
echo $search_res[$i][$j];
}
}
}
}