2009-06-19 2 views
22

Ich bin relativ neu in MySQL und habe ein Problem, das mich seit einer Weile nervt. Ich habe versucht, überall nach der Antwort zu suchen, habe aber noch keine akzeptable Lösung gefunden. HierSortierung MYSQL Volltextsuche nach Relevanz

ist die Abfrage, die ich bin derzeit läuft die bestmögliche Übereinstimmung für einen bestimmten Suchbegriff zu finden:

$query="SELECT * from `vocabulary` WHERE translation = 'word' OR translation LIKE '%word%'"; 

Die Ergebnisse es Erträge sind umfassende, dass sie alle relevanten Zeilen umfassen. Sie sind jedoch nicht in einer bestimmten Reihenfolge sortiert, und ich möchte diejenigen mit einer genauen Übereinstimmung zuerst angezeigt haben, wenn ich Ergebnisse in PHP drucke. So:


1 | wort < -exakt match
2 | Kreuzworträtsel < - Teiltreffer alphabetisch sortiert/
3 | Wörter
4 | Sprachkünstler


Vielen Dank im Voraus für Ihre Hilfe.

-macspacejunkie

+0

UPDATE: Vielen Dank für die Unterstützung! Genau das, wonach ich gesucht habe. Grüße, -macspacejunkie – user125591

+0

Wenn Ihnen jemand geholfen hat, überprüfen Sie bitte ihre Antwort – Jason

Antwort

14
SELECT * from vocabulary 
WHERE translation like 'word' 
union all 
SELECT * from vocabulary 
WHERE translation LIKE '%word%' and translation not like 'word' 

listet passt exakt erste

+1

Das ist eine sehr schreckliche Art, Dinge in großen Tabellen zu tun. Ziehen Sie die Verwendung der 'FULLTEXT'-Suche für viel schnellere Abfragen in Betracht. – OverCoder

28

LIKE nicht fulltext search ist. In der Volltextsuche gibt MATCH(...) AGAINST(...) einen übereinstimmenden Wert zurück, der ungefähr als Relevanz angenähert werden kann.

21

Sie können eine gute Relevanzsuche erhalten, indem Sie einen Volltextindex erstellen und dann mit Ihrem Suchbegriff übereinstimmen.

So etwas wie das sollte funktionieren.

ALTER TABLE `vocabulary` ADD FULLTEXT INDEX `SEARCH`(`translation`); 

SELECT *, MATCH(translation) AGAINST ('+word' IN BOOLEAN MODE) AS relevance 
FROM `vocabulary` 
WHERE MATCH(translation) AGAINST ('+word' IN BOOLEAN MODE) 
ORDER BY relevance DESC 

Weitere Informationen finden Sie in der MySQL Reference Manual.

+13

Wenn der Befehl MATCH in der WHERE-Klausel verwendet wird, sortiert MySQL die Zeilen automatisch von der höchsten zur niedrigsten Relevanz. – ejunker

+0

Vielen Dank, Rich Adams und ejunker für diesen. Beide sehr gute Punkte. Ich hatte einen Kunden, der mir die Relevanz für die Suche auf den Kopf stellte und das ist eine große Hilfe. – Volomike

+0

@ejunker das wäre toll. Könnten Sie bitte auf einen Hinweis darauf hinweisen? Dies gilt auch für BOOLEAN MODE? Vielen Dank. – Havok

5

Ich habe das gleiche Problem gesucht und noch nicht die perfekte Antwort für meine Situation gefunden, aber das könnte für Sie nützlich sein. Ich bin ziemlich neu in der Volltextsuche, also helfen mir auch Experten.

Ich mache zwei MATCH() AGAINST() Anweisungen in der Auswahl und kombinieren die Punktzahl von jedem, um die Gesamtrelevanz zu bilden. Das Zuweisen verschiedener Multiplikatoren ermöglicht es mir, die Wichtigkeit jeder Ergebnismenge zu konfigurieren.

Meine erste MATCH() würde gegen den wörtlichen (oder genauen) Suchbegriff mit doppelten Anführungszeichen überprüfen Meine zweite MATCH würde normal überprüfen. Ich wende einen höheren Multiplikator an die erste Übereinstimmung an, so sollte es einen höheren Relevanzwert haben, wenn es gefunden wird.

So etwas wie das.

SELECT *, ((MATCH(indexes) AGAINST ('"search_terms"' IN BOOLEAN MODE) * 10) 
      + (MATCH(indexes) AGAINST ('search_terms' IN BOOLEAN MODE) * 1.5)) AS relevance 
FROM ... 
WHERE ... 
     AND (MATCH (indexes) AGAINST ('"search_terms"' IN BOOLEAN MODE) > 0 
      OR MATCH (indexes) AGAINST ('search_terms' IN BOOLEAN MODE) > 0) 
     ... 
ORDER BY relevance DESC 

Wenn Sie ausführen, um die Funktion EXPLAIN verwenden zu zeigen, wie die Abfrage funktioniert, sollten Sie feststellen, dass die zusätzliche MATCH() AGAINST() Klauseln hinzufügen Dont tatsächlich einen zusätzlichen Overhead auf die Abfrage aufgrund der Art und Weise MySQL funktioniert.

2

Ihre Anfrage benötigt nur ein paar Änderungen, um die gewünschte Bestellung zu erhalten.

SELECT * 
FROM vocabulary 
WHERE translation LIKE '%word%' 
ORDER BY translation <> 'word', translation; 

Wenn translation genau 'word', wird es an der Spitze der Ergebnisse sein. Dies liegt daran, translation <> 'word' wird sein, wenn es eine genaue Übereinstimmung gibt, die vor der kommt, die für alle anderen Ergebnisse zurückgegeben wird. Die restlichen Ergebnisse werden danach aufgrund der , translation alphabetisch sortiert.

Diese Abfrage vermeidet zwei Abfragen wie die ausgewählte Antwort mit ihrer UNION macht. Darüber hinaus benötigt Ihre Abfrage nicht translation = 'word' OR translation LIKE '%word%', da die zweite Hälfte immer ausgeführt wird und eine Obermenge des ersten Teils ist.

Für die Suche nach einer Antwort, die eine tatsächliche Volltextsuche verwendet, finden Sie in den anderen, höher bewerteten Antworten.