2016-01-15 11 views
8

Ich habe einige articles und issues gelesen, konnte aber keine befriedigende Lösung finden. Ich möchte verwandte Datensätze aus der Datenbank auswählen, wenn ein Benutzer ein Formular ausfüllt. Auf dieselbe Weise funktioniert die Funktionalität auf dieser Site, wenn Sie eine Frage stellen.MySQL Volltextsuche mit Wortgrenzen

Betrachten Sie mit den folgenden drei Datensätze in der Spalte einer Datenbanktabelle subject

+---+---------------------------------------------------+ 
| 1 | Pagina aanmaken en beter doorzoekbaar maken  | 
+---+---------------------------------------------------+ 
| 2 | Sorteerfunctie uitbreiden in zoek-en-boek functie | 
+---+---------------------------------------------------+ 
| 3 | Zoek de verschillen tussen de pagina's   | 
+---+---------------------------------------------------+ 

ich meine Suchabfrage mit dem Wort beginnen zoek so möchte ich auf den Begriff zoek die relevantesten Ergebnisse aus der Datenbank abzufragen. Ich kam mit der folgenden Abfrage auf:

SELECT 
    id, 
    subject, 
    MATCH(
     subject 
    ) 
    AGAINST(
     'zoek*' 
     IN BOOLEAN MODE 
    ) 
    AS 
     score 
FROM 
    Issues 
WHERE 
    MATCH(
     subject 
    ) 
    AGAINST(
     'zoek*' 
     IN BOOLEAN MODE 
    ) 

Wenn ich diese Abfrage ausführen ich alle Datensätze erwartet würde zu zeigen, und (wahrscheinlich, ich weiß nicht, wie die Spezifität in MySQL funktioniert) ID 3 oben angezeigt (weil genaues Wort übereinstimmt).

Stattdessen waren die Ergebnisse der Abfrage nur Zeile 2 und 3 mit genau der gleichen Punktzahl (0.031008131802082062).

Was muss ich in meiner Abfrage ändern, um passenden Datensätzen zu entsprechen? Auch unter Berücksichtigung, dass Benutzer Schlüsselwörter oder Sätze eingeben können.

+0

Warum erwartet Sie alle Datensätze in Folge zu sehen? Der erste Eintrag enthält kein Wort 'zoek' –

+0

@ r-costas Antwort ist korrekt. Vielleicht möchten Sie auch auf http://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html nachsehen, wie Relevanz-Ranking berechnet wird. MySQL macht, was es hier machen soll. Wenn Sie eine umfangreichere Textsuche benötigen, müssen Sie wahrscheinlich etwas Lucene-basiertes (Solr, Elasticsearch, usw.) verwenden. – evanv

Antwort

0

Es gibt eine workaound für Ihren Fall:

SELECT 
    id, 
    subject, 
    IF (subject LIKE "zoek %" OR subject LIKE "% zoek %" OR subject LIKE "% zoek", 
     1, 
     IF (subject LIKE "% zoek%", 
      0.5, 
      IF (subject LIKE "%zoek%", 
       0.2, 
       0) 
      ) 
     ) as score 
FROM 
    Issues 
WHERE subject LIKE "%zoek%" 
ORDER by score DESC 

Erwartetes Ergebnis:

+---+---------------------------------------------------+------+ 
|id | subject           |score |  
+---+---------------------------------------------------+------+ 
|3 | Zoek de verschillen tussen de pagina's   | 1 | 
+---+---------------------------------------------------+------+ 
|2 | Sorteerfunctie uitbreiden in zoek-en-boek functie | 0.5 | 
+---+---------------------------------------------------+------+ 
|1 | Pagina aanmaken en beter doorzoekbaar maken  | 0.2 | 
+---+---------------------------------------------------+------+ 
+0

Dies funktioniert genau wie ich will, wenn ich nach einem einzelnen Wort suche. Ein Nebenproblem ist, dass ich mehrere Wörter suchen möchte. Wenn ich den Suchbegriff zB in "de zoek" ändere, bekomme ich keine Datensätze. Aber danke für diesen Ansatz bisher! – Maurice

2

Die MySQL-Volltextsuche unterstützt keine Suffixe.

Um die erste Zeile zu erhalten, müssten Sie eine Übereinstimmung mit '* zoek *' machen, was momentan nicht erlaubt ist.

Die Alternative ist

SELECT id, subject 
FROM Issues 
WHERE subject LIKE '%zoek%' 
0

Leider zu verwenden ...

Mitte des Wortes (doorzoekbaar) ist per definitionem von FULLTEXT MySQL, nicht etwas, das gefunden wird. FULLTEXT hat kein Konzept von "zusammengesetzten Substantiven", also wird es nicht versuchen, das Wort auseinander zu nehmen.

Die Definition eines "Wortes" in FULLTEXT gibt 'Strich' und 'Raum' die gleiche Bedeutung - nämlich eine Wortgrenze. Also, zoek de... und zoek-... sind gleich gewichtet.

Betrachten Sie Solr, Lucene und andere "Fulltext-Lösungen" von Drittanbietern. Sie können (oder können nicht) liefern, was Sie wollen.

zoek* und +zoek*, bei der Ausführung mit IN BOOLEAN MODEwirdzoekbaar finden.

1

testen Abfragen für unterschiedliche Ergebnisse:

  1. alle Themen auswählen, die mit dem Buchstaben "z" beginnt:
    SELECT ID, Subject FROM table_name WHERE Subject LIKE 'z%';

  2. markiert Thema, das mit dem Buchstaben "z" endet:
    SELECT ID, Subject FROM table_name WHERE Subject LIKE '%z';

  3. alle Thema Wählen Sie das Muster "zoek" enthält:
    SELECT ID, Subject FROM table_name WHERE Subject LIKE '%zoek%';

1

Wie andere empfohlen, FULLTEXT Indizes MySQL unterstützt keine führenden Platzhalter, und daher nicht bei der Suche nach Suffixe helfen kann.

jedoch die neue ngram Full-Text Parser helfen könnten:

Der eingebaute MySQL Volltext-Parser den Leerraum zwischen Wörtern als Trennzeichen verwendet, um zu bestimmen, wo Wörter beginnen und enden, was eine Einschränkung ist bei der Arbeit mit ideografischen Sprachen, die keine Worttrennzeichen verwenden. Um diese Einschränkung zu umgehen, stellt MySQL einen ngram-Volltext-Parser (...) zur Verfügung.

Ein Ngram ist eine zusammenhängende Folge von n Zeichen aus einer gegebenen Textfolge. Der Ngram-Parser zerlegt eine Textsequenz in eine zusammenhängende Folge von n Zeichen.

Wie ich nie diese Funktion verwendet haben, kann ich zu diesem Thema helfen nicht weiter. Beachten Sie jedoch:

Da ein Ngram FULLTEXT Index nur Ngrams enthält und keine Informationen über den Begriffsbeginn enthält, können Platzhaltersuchen unerwartete Ergebnisse liefern.