Volltextsuche (Anfaenger)

Volltextsuche (Anfaenger)

am 13.08.2005 14:57:07 von Fabian Mack

Hallo,

bin absoluter Anfaenger was PHP und MySQL betrifft.
Fuer den Anfang habe ich mir eine DVD-Datenbank erstellt. Die Filme
werden in einer HTML-Seite in einer Tabelle ausgegeben. Das funktioniert
auch alles super, aber momentan mache ich mich an die Verfeinerung. Also
muss eine Volltextsuche her.
Ich habe einen Index ueber die Felder "name" und "darsteller" erstellt.
Die Suche sieht also so aus:

$result = mysql_query("SELECT * FROM dvd WHERE MATCH(name) AGAINST
('$suchwort') or MATCH(darsteller) AGAINST('$suchwort')");

Ueber eine Schleife gebe ich dann die Filme wieder in einer Tabelle aus:

while($row = mysql_fetch_object($result)){
....
}

Das funktioniert ebenfalls bestens. Wird allerdings nichts gefunden,
moechte ich einen Satz wie "nix gefunden" ausgeben. Und das ist das
Problem. Sieht momentan so aus:

if ($result == '0'){
echo 'Suche beendet, es wurde kein Datensatz gefunden';
}
else{
Schleife
}

Das Problem ist also die Bedingung. Wie mache ich das?

Noch was komisches: In der Datenbank gibt es den Film "28 Days Later".
Wie gesagt, die Suche funktioniert wunderbar, nur wenn ich nach "Later"
suche wird nichts gefunden. Ist das ein Schluesselwort oder so?

Danke

--
Gruesse aus Schwaebisch Hall - Fabian

Re: Volltextsuche (Anfaenger)

am 13.08.2005 21:14:02 von dev-null-use-reply-adress

Fabian Mack schrieb:

> Ich habe einen Index ueber die Felder "name" und "darsteller" erstellt.

Also ein kombinierter Index oder zwei einzelne? Das macht u.U.
einen grossen Unterschied aus. Siehe Manual:
http://dev.mysql.com/doc/mysql/en/fulltext-search.html

Und ist es auch ein Volltextindex oder doch nur ein "normaler"?

> Die Suche sieht also so aus:
>
> $result = mysql_query("SELECT * FROM dvd WHERE MATCH(name) AGAINST
> ('$suchwort') or MATCH(darsteller) AGAINST('$suchwort')");

Das kannst aber auch mit einem MATCH machen.

SELECT
FROM dvd
WHERE MATCH(name, darsteller)
AGAINST ('$suchwort')

Desweiteren würde ich im binary modus suchen, damit auch Wortbestandeile
gefunden werden können und Du mehr Suchoptionen hast.
http://dev.mysql.com/doc/mysql/en/fulltext-boolean.html

Nicht zu vergessen:
16.14. Warum soll ich nicht SELECT * schreiben?
http://www.php-faq.de/q/q-sql-select.html

> Ueber eine Schleife gebe ich dann die Filme wieder in einer Tabelle aus:
>
> while($row = mysql_fetch_object($result)){

In die Runde frag:
Wo kommt nur immer dieses mysql_fetch_object her? Ich habe nie
verstanden, warum es diese Funktion überhaupt gibt. Ist es nicht
ein unnötiger Overhead, aus Abfrageergebnissen Objekte zu machen?

Benutze besser mysql_fetch_row() oder mysql_fetch_assoc().

> Das funktioniert ebenfalls bestens. Wird allerdings nichts gefunden,
> moechte ich einen Satz wie "nix gefunden" ausgeben. Und das ist das
> Problem. Sieht momentan so aus:
>
> if ($result == '0'){
> echo 'Suche beendet, es wurde kein Datensatz gefunden';
> }
> else{
> Schleife
> }
>
> Das Problem ist also die Bedingung. Wie mache ich das?

if (mysql_num_rows($result) === 0)

> Noch was komisches: In der Datenbank gibt es den Film "28 Days Later".
> Wie gesagt, die Suche funktioniert wunderbar, nur wenn ich nach "Later"
> suche wird nichts gefunden. Ist das ein Schluesselwort oder so?

Könnte sein das Deine Indexe falsch sind (s.o.), oder daß later so
oft vorkommt, daß MySQL es als Stoppwort betrachtet, oder ...
ich weis auch nicht.
Lies am besten mal das ganze Kapitel zur Volltextsuche im
MySQL Manual.


Gruß
JPM

Re: Volltextsuche (Anfaenger)

am 14.08.2005 00:19:17 von Fabian Mack

Hallo Jens,

Jens Peter Möller produzierte mit Hilfe seiner Tastatur folgendes:

> Fabian Mack schrieb:
>
> > Ich habe einen Index ueber die Felder "name" und "darsteller"
> > erstellt.
>
> Also ein kombinierter Index oder zwei einzelne? Das macht u.U.
> einen grossen Unterschied aus. Siehe Manual:
> http://dev.mysql.com/doc/mysql/en/fulltext-search.html
>
> Und ist es auch ein Volltextindex oder doch nur ein "normaler"?


Ja, sind zwei einzelne Volltext-Indizes.



>
> > Die Suche sieht also so aus:
> >
> > $result = mysql_query("SELECT * FROM dvd WHERE MATCH(name) AGAINST
> > ('$suchwort') or MATCH(darsteller) AGAINST('$suchwort')");
>
> Das kannst aber auch mit einem MATCH machen.

Hmm, ich hab echt alles ausprobiert, das mit einem MATCH zu machen, aber
da bin ich natuerlich nicht draufgekommen... *g*. Danke!

[snip (binary modus)]

> Nicht zu vergessen:
> 16.14. Warum soll ich nicht SELECT * schreiben?
> http://www.php-faq.de/q/q-sql-select.html

Ja, hab ich schon gelesen. Hab die ganzen Feldnamen hier nur durch den *
ersetzt, damit es nicht so lang ist.


[snip (mysql_fetch_object)]


>
> > Noch was komisches: In der Datenbank gibt es den Film "28 Days
> > Later". Wie gesagt, die Suche funktioniert wunderbar, nur wenn ich
> > nach "Later" suche wird nichts gefunden. Ist das ein Schluesselwort
> > oder so?
>
> Könnte sein das Deine Indexe falsch sind (s.o.), oder daß later so
> oft vorkommt, daß MySQL es als Stoppwort betrachtet, oder ...
> ich weis auch nicht.
> Lies am besten mal das ganze Kapitel zur Volltextsuche im
> MySQL Manual.

Hmm, ob die Indizes jetzt falsch sind kann ich natuerlich nicht 100%ig
ausschliessen, wuerde aber mal behaupten, dass die passen. Ich finde ja
auch wirklich alles andere. Wenn ich z.B. nach "days" suche find ich den
Film auch. Nur mit "later" geht's net...
Das mit dem Stoppwort hab ich mir auch schon ueberlegt, aber das kommt
sonst in keinem anderen Titel vor.


> Gruß
> JPM

Dank dir fuer die wirklich ausfuehrliche Antwort!

--
Gruesse aus Schwaebisch Hall - Fabian

Re: Volltextsuche (Anfaenger)

am 14.08.2005 00:45:14 von Niels Braczek

Jens Peter Möller schrieb:

> In die Runde frag:
> Wo kommt nur immer dieses mysql_fetch_object her? Ich habe nie
> verstanden, warum es diese Funktion überhaupt gibt. Ist es nicht
> ein unnötiger Overhead, aus Abfrageergebnissen Objekte zu machen?

Naja, schließlich ist es hip, objektorientiert zu programmieren. Viele
glauben wohl, daher mit dieser Funktion voll im Trend zu liegen.
Overhead wird dadurch nicht erzeugt. Technisch ist ein Objekt ohne
Methoden doch nichts anderes als ein assoziatives Array mit -> statt []
als Zugriffsoperator.
*Wirklich* Sinn machen täte diese Funktion, wenn man ihr sagen könnte,
welche Klasse instanziert werden soll. Das würde ein extra binding ersparen.

MfG
Niels

--
| http://www.kolleg.de · Das Portal der Kollegs in Deutschland |
| http://www.bsds.de · BSDS Braczek Software- und DatenSysteme |
| Webdesign · Webhosting · E-Commerce · Mambo Content Management |
`----------------------------------------------------------- -----´

Re: Volltextsuche (Anfaenger)

am 14.08.2005 19:36:30 von Tomasz Lubowiecki

Fabian Mack schrieb:
>
> $result = mysql_query("SELECT * FROM dvd WHERE MATCH(name) AGAINST
> ('$suchwort') or MATCH(darsteller) AGAINST('$suchwort')");
> ...
>
> Noch was komisches: In der Datenbank gibt es den Film "28 Days Later".
> Wie gesagt, die Suche funktioniert wunderbar, nur wenn ich nach "Later"
> suche wird nichts gefunden. Ist das ein Schluesselwort oder so?

Versuch es mal mit:

$result = mysql_query("SELECT * FROM dvd WHERE name LIKE
'%".$suchwort."%' OR darsteller LIKE '%".$suchwort."%'");

Solange sich die Anzahl der Datensätze in Rahmen hält, müsste dies eine
gute Lösung sein. Im Rahmen bedeutet ca. unter 100 Tsd.