SELFPHP: Version 5.8.2 Befehlsreferenz - Tutorial – Kochbuch – Forum für PHP Einsteiger und professionelle Entwickler

SELFPHP


Professional CronJob-Service

Suche



CronJob-Service    
bei SELFPHP mit ...



 + minütlichen Aufrufen
 + eigenem Crontab Eintrag
 + unbegrenzten CronJobs
 + Statistiken
 + Beispielaufrufen
 + Control-Bereich

Führen Sie mit den CronJobs von SELFPHP zeitgesteuert Programme auf Ihrem Server aus. Weitere Infos



:: Buchempfehlung ::

PHP 5.3 & MySQL 5.1

PHP 5.3 & MySQL 5.1 zur Buchempfehlung
 

:: Anbieterverzeichnis ::

Globale Branchen

Informieren Sie sich über ausgewählte Unternehmen im Anbieterverzeichnis von SELFPHP  

 

:: Newsletter ::

Abonnieren Sie hier den kostenlosen SELFPHP Newsletter!

Vorname: 
Name:
E-Mail:
 
 

Zurück   PHP Forum > SELFPHP > MySQLi/PDO/(MySQL)

MySQLi/PDO/(MySQL) Anfänger, Fortgeschrittene oder Experten können hier Fragen und Probleme rund um MySQLi/PDO/(MySQL) diskutieren

Antwort
 
Themen-Optionen Ansicht
  #1  
Alt 05.01.2009, 01:22:09
mgutt mgutt ist offline
Anfänger
 
Registriert seit: May 2008
Beiträge: 65
MySQL MATCH: bestimmte Spalte negieren / gewichten

Hallo,

ich möchte gerne sowas erreichen:
Code:
SELECT *
FROM articles
WHERE MATCH (title,~body) AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE)
Wie man sieht, würde ich gerne "body" negieren, so dass ein Ergebnis im "title" höher gewichtet würde. Leider geht das nicht so, wie ich es jetzt beispielhaft dargestellt habe. Gibt es noch eine andere Möglichkeit?

EDIT:
Mir fällt aktuell nur die Möglichkeit ein, noch eine dritte Spalte hinzuzufügen, in der die Wörter aufgenommen werden, über die der Artikel gefunden wurde. D.h. wenn die Nutzer bestimmte Artikel bevorzugen, rutschen sie mit der Zeit nach vorne, aber das wäre nur eine Notlösung.

EDIT2:
Suche nach Genauigkeit jetzt im Forum realisiert: www.maxrev.de

Geändert von mgutt (10.01.2009 um 19:31:06 Uhr)
Mit Zitat antworten
  #2  
Alt 05.01.2009, 07:06:26
Crisps Crisps ist offline
Junior Member
 
Registriert seit: Oct 2008
Alter: 47
Beiträge: 274
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Man könnte den Score von title multiplizieren und damit im ORDER BY das ganze auf den Titel gewichten - etwa so:
Code:
SELECT title
     , body
     , (MATCH(title) AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) * 2) AS score_title
     , MATCH(body) AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AS score_body
  FROM articles
 WHERE MATCH(title, body) AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE)
ORDER
    BY score_title DESC
     , score_body DESC;
Mit Zitat antworten
  #3  
Alt 05.01.2009, 07:30:27
mgutt mgutt ist offline
Anfänger
 
Registriert seit: May 2008
Beiträge: 65
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Dann wäre ja 100% Gewicht auf title oder nicht? Also erst würden nur Ergebnisse aus title angezeigt und dann die mit body oder?

Geändert von mgutt (05.01.2009 um 07:32:45 Uhr)
Mit Zitat antworten
  #4  
Alt 05.01.2009, 07:50:06
Crisps Crisps ist offline
Junior Member
 
Registriert seit: Oct 2008
Alter: 47
Beiträge: 274
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Ja, Ergebnisse aus dem Titel haben Priorität vor Ergebnissen aus Body.

Geändert von Crisps (05.01.2009 um 09:59:07 Uhr) Grund: Typo
Mit Zitat antworten
  #5  
Alt 05.01.2009, 10:49:06
Crisps Crisps ist offline
Junior Member
 
Registriert seit: Oct 2008
Alter: 47
Beiträge: 274
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Wenn man vollen Zugriff auf den Server hat, kann man auch Sphinx für MySQL installieren.

http://www.sphinxsearch.com/

Sphinx unterstützt diese individuelle Gewichtung von Spalten und ist auch effizienter als Fulltext.
Mit Zitat antworten
  #6  
Alt 05.01.2009, 15:42:37
mgutt mgutt ist offline
Anfänger
 
Registriert seit: May 2008
Beiträge: 65
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Sphinx sieht interessant aus und ich habe daher etwas recherchiert:

Auf Grund eines Mods, der für vBulletin existiert, kann man verschiedenes erkennen:
Code:
The Good:
Search this forum 
Search this thread 
Find all posts by User 
Find all threads started by User 
"Search Entire Posts"/"Search Titles Only" and "Show Results as Threads"/"Show Results as Posts" in all four combinations supported 
"Search Entire Posts" can be sorted by rank/post.dateline (postuserid, forumid will sort by integer) 
"Search Titles Only" can be sorted by rank, last reply date, first post date, number of replies (views if you add that value to sphinx.conf) 
Really fast 

The Bad:
This means you can't sort posts by title, number of replies/views, thread start date, last reply date (Sphinx doesn't have this data).* 
You could possibly add this to sphinx.conf but it will only be as good as your last full post index update 
"Find Threads with At Least/Most X Replies" doesn't work when "Search Entire Posts" 
Search results are delayed (depending on how often you run indexer) 
"New Posts" not supported... too much logic in the query?!
Der Index ist also zeitversetzt und bestimmte Sortierungsvarianten scheinen nicht möglich zu sein, inbesondere wenn es um Aktualität der Daten geht. Also z.B. bei Sortierung nach Datum. Also hat Sphinx auch so einige Einschränkungen.

Ansonsten habe ich noch einen Vortrag mit Benchmarks gefunden.

Weiterhin fand ich hier eine Erklärung zum Einsatz von Sphinx:
http://www.ibm.com/developerworks/li...-sphinxsearch/

Aktuell umfasst die Artikeltabelle ca. 500 MB. Wenn ich das richtig verstehe, sollte ich diese eine Tabelle in eine getrennte Datenbank auslagern, die ich nur von Sphinx abarbeiten lasse, so dass ich eine saubere Trennung zu den restlichen MySQL-Abfragen habe.

Also nach der Recherche bin ich überzeugt davon, dass Sphinx schneller ist und dazu mein Problem lösen kann. Weiterhin habe ich dadurch herausgefunden, dass Dein erster Vorschlag mit der Unterscheidung zwischen score_title und score_body extrem langsam sein wird.

Sphinx speichert die Wortposition, d.h. das es nicht wie bei MySQL Full-Text nur darauf ankommt, dass ein Wort da ist und das noch mehrfach, sondern dass die Ergebnisse höher gewertet werden, wo die Suchwörter näher zusammenliegen.

Sphinx hat aber auch einen großen Nachteil. Insbesondere in Foren, wo jeden Tag neue Diskussionen gestartet werden, fallen neue solange raus, solange der Index nicht aktualisiert wurde. Dieser Nachteil ist aber auch wieder ein Vorteil: Hinzugefügte Datensätze werden nicht mehr indexiert und landen so schneller in der Tabelle.

Aber ich frage mich, wie lange es noch dauert bis MySQL eine eigene Lösung anbieten wird. Ich möchte mich ungern in ein neues System einarbeiten, wenn es bald von Haus aus integriert wäre.
Mit Zitat antworten
  #7  
Alt 06.01.2009, 01:39:46
mgutt mgutt ist offline
Anfänger
 
Registriert seit: May 2008
Beiträge: 65
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Hi,

ich habe jetzt mal was versucht, dessen Ergebnis ich nicht verstehe. Ich bin hingegangen und habe den Titel in eine zweite Spalte title2 kopiert, dann auf alle drei Spalten einen fulltext-Index gesetzt und erneut gesucht. Wider erwartend hat sich das Ergebnis überhaupt nicht geändert. Müsste jetzt nicht die Sortierung das mehrfache Vorkommen von Keywords im Titel doppelt so stark gewichten?

Gruß
Mit Zitat antworten
  #8  
Alt 06.01.2009, 10:07:37
Crisps Crisps ist offline
Junior Member
 
Registriert seit: Oct 2008
Alter: 47
Beiträge: 274
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Ich hab mir die oben gespostete Query nur als Lösungsansatz ausgedacht - ob das auch alles 100% funktioniert kann ich nicht sagen. Auch muss man sich vielleicht mal den Fulltext-Index genauer anschauen und wie sich die Kombination von title,body im WHERE/MATCH Teil und das jeweils einmalige Aufrufen der beiden Spalten im SELECT Teil auf die Indexnutzung auswirkt.

Mit Sphinx hab ich ehrlich gesagt auch keine Erfahrung. Mich verwirrt vor allem, dass Sphinx mit InnoDB und Myisam funktionieren soll, aber dann in den Dokumenten ein CREATE TABLE- Beispiel mit ENGINE=SPHINX ausgeführt wird. Aber ich hab mich damit noch nicht wirklich befasst - Leider scheint es ja auch nirgendwo ein einfaches Sphinx Tutorial/HOWTO zu geben...

Zitat:
Aber ich frage mich, wie lange es noch dauert bis MySQL eine eigene Lösung anbieten wird. Ich möchte mich ungern in ein neues System einarbeiten, wenn es bald von Haus aus integriert wäre.
In MySQL 5.1 wurde die Boolean-Suche angeblich um 500%-1000% beschleunigt. Ok, das sind keine neuen Features, aber damit kommt man schon mal weiter in Sachen Performance.

Geändert von Crisps (06.01.2009 um 10:58:09 Uhr)
Mit Zitat antworten
  #9  
Alt 06.01.2009, 16:08:05
mgutt mgutt ist offline
Anfänger
 
Registriert seit: May 2008
Beiträge: 65
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Sphinx funktioniert mit anderen DB-Typen, weil Sphinx den Full-Text Index darstellt. Im Endeffekt ist Sphinx also nichts anderes als ein Index und der wurde sehr stark auf die Suche optimiert, während man die Live-Indexierung (also das nachträgliche Hinzufügen von Indexen) außer acht lässt. Wenn ich das richtig verstanden habe, kann man bei Sphinx auch keinen neuen Eintrag hinzufügen, sondern muss den gesamten Index neu erstellen, daher auch das Problem mit den weniger aktuellen Daten.

Ich habe bei mir die Suche vor ein paar Tagen von aktuellste Einträge zuerst auf genauste Einträge zuerst umgestellt und bin wirklich nicht zufrieden mit dem was MySQL mir da anbietet.

Ich habe z.B. eine Suche nach einem Wort generiert. Es gibt mehrere Themen, die dieses Wort im Titel und im Text haben. An Position 1 ist aber ein Eintrag, der hat das Wort nur einmal im Text. Daher wäre ich auch mal daran interessiert was MySQL da eigentlich treibt. Und wie gesagt hat es nichts gebracht, dass ich den Titel doppelt abarbeite, was ich eigentlich für logisch erachtete.

Deine Idee mit der Relevanz habe ich jetzt nicht getestet, weil in dem Benchmark dieses Beispiel angegeben war:
Code:
select title,match(title) against ("post office" in boolean mode)*10 + 
match(content) against("post office" in boolean mode) relevance  from 
cont where match (title,content) against ("post office" in boolean mode) 
order by relevance desc  limit 10;
und als Ausführungszeit: 3 min 38.35 sec (!)

Wie Du siehst war Deine Idee gar nicht so schlecht, man muss nur eben beide relevance-Werte addieren (eigentlich logisch) und dann nach relevance sortieren, aber meiner Meinung nach braucht man dafür nicht nur einen Fulltext-Index, sondern drei (title+content, title, content).

Aber ich mach das jetzt einfach mal. Ich teste das ganze gerade mal und geb dann Feedback.

EDIT:
Also die Suche nach einer Phrase:
- mit einem einfachen boolean match und einem fulltext-index auf title+content dauert 0,42 - 0,69 Sekunden
- mit drei boolean matches (zwei für den relevance-wert im SELECT, ein normaler) und ORDER BY relevance und einem fulltext-index auf title+content dauert 0,84 - 1,33 Sekunden
- mit drei boolean matches (zwei für den relevance-wert im ORDER BY, ein normaler) und einem fulltext-index auf title+content dauert 0,43 - 1,01 Sekunden (relevance braucht man ja nicht im resultat)

Macht es Sinn neben dem index auf title+content noch zwei Einzelne für title und content zu generieren, um die matches im ORDER BY zu beschleunigen? Weil bei MYSQL steht:
Zitat:
The MATCH() column list must match exactly the column list in some FULLTEXT index definition for the table, unless this MATCH() is IN BOOLEAN MODE. Boolean-mode searches can be done on non-indexed columns, although they are likely to be slow.
Weil phpmyadmin gibt folgendes aus:
Zitat:
Es sollte nicht mehr als ein Index des Typs FULLTEXT für die Spalte `post_subject` gesetzt sein
EDIT2:
Ok laut hier darf ich die Meldung von phpmyadmin ignorieren:
http://www.issociate.de/board/post/3...e_separat.html

Der ist sogar hingegangen und hat den Index über beide Spalten entfernt, aber so viel ich weiß geht das nicht. MySQL resultiert doch dann einen Fehler beim MATCH über zwei Spalten?!

EDIT3:
Peinlich.. ich habe gerade herausgefunden, dass die Relevanz flöten geht, weil meine letzte Abfrage, um die kompletten Daten zu schaufeln "id IN(3456,123,31223,2)" dazu führt, dass die Ergebnisse immer nach ID (2,123,3456,31223) sortiert werden. MySQL ignoriert also leider die Reihenfolge in IN(). Bevor ich das nicht löse, wird es nichts mit der Relevanz.

Geändert von mgutt (06.01.2009 um 18:14:46 Uhr)
Mit Zitat antworten
  #10  
Alt 06.01.2009, 18:05:51
Crisps Crisps ist offline
Junior Member
 
Registriert seit: Oct 2008
Alter: 47
Beiträge: 274
AW: MySQL MATCH: bestimmte Spalte negieren / gewichten

Ich hab gerade selber mal ein paar Benchmarks mit Fulltext gemacht und der oben gesposteten Query (mit paar anderen search terms).

ca. ~80.000 Einträge und die Query in einem 10x Loop:

Mit Fulltext nur auf title: 20 Sekunden
Mit Fulltext nur auf content: 20 Sekunden

Mit Fulltext auf title+content: 0.33 Sekunden
Mit Fulltext nur auf content+title: 0.33 Sekunden

Mit Fulltext auf title+content und noch einem extra FX auf title oder content: 0.44 Sekunden

Man sieht, ein Fulltext auf title+content reicht völlig aus.

Zitat:
Der ist sogar hingegangen und hat den Index über beide Spalten entfernt, aber so viel ich weiß geht das nicht. MySQL resultiert doch dann einen Fehler beim MATCH über zwei Spalten?!
Ich denke, MySQL sucht dann einfach ohne Index in der anderen Spalte...

Zitat:
Peinlich.. ich habe gerade herausgefunden, dass die Relevanz flöten geht, weil meine letzte Abfrage, um die kompletten Daten zu schaufeln "id IN(3456,123,31223,2)" dazu führt, dass die Ergebnisse immer nach ID (2,123,3456,31223) sortiert werden. MySQL ignoriert also leider die Reihenfolge in IN(). Bevor ich das nicht löse, wird es nichts mit der Relevanz.
Hm, ich glaube mich dunkel erinnern zu können, dass es eine Möglichkeit gibt, dass diese Reihenfolge doch beachtet wird. Wie das geht? Ich wünschte ich könnte mich daran erinnern, vielleicht war es aber doch nur ein Hirngespinst...

Geändert von Crisps (06.01.2009 um 18:06:17 Uhr)
Mit Zitat antworten
Antwort


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind aus.
[IMG] Code ist aus.
HTML-Code ist aus.

Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
CSV - nur bestimmte Zeilen in mysql schreiben PrometheusXDE PHP Grundlagen 4 11.11.2008 17:13:35
MYSQL Spalte einer Tabelle leeren wotuzu17 PHP für Fortgeschrittene und Experten 2 01.08.2008 01:36:51
Auf bestimmte Error Meldungen von MySql reagieren koerschgen2001 PHP Grundlagen 8 11.03.2006 19:35:04
bestimmte Reihe einer Spalte auslesen Prometheus PHP Grundlagen 3 22.01.2006 20:17:10
mysql Tabelleninhalt exportieren und bestimmte Spalten in eine andere Tabelle importi Workaholic4u MySQLi/PDO/(MySQL) 1 21.02.2004 17:50:03


Alle Zeitangaben in WEZ +2. Es ist jetzt 12:44:11 Uhr.


Powered by vBulletin® Version 3.8.3 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.


© 2001-2024 E-Mail SELFPHP OHG, info@selfphp.deImpressumKontakt