web-dev-qa-db-de.com

Wie implementiere ich eine Stichwortsuche in MySQL?

Ich bin neu in der SQL-Programmierung.

Ich habe einen Tabellenjob, in dem die Felder id, position, category, location, salary range, description, refno.

Ich möchte eine Stichwortsuche vom Frontend aus implementieren. Das Schlüsselwort kann sich in einem der Felder der obigen Tabelle befinden.

Dies ist die Abfrage, die ich versucht habe, aber sie besteht aus so vielen doppelten Zeilen:

SELECT
    a.*,
    b.catname
FROM
    job a,
    category b
WHERE
    a.catid = b.catid AND
    a.jobsalrange = '15001-20000' AND
    a.jobloc = 'Berkshire' AND
    a.jobpos LIKE '%sales%' OR
    a.jobloc LIKE '%sales%' OR
    a.jobsal LIKE '%sales%' OR
    a.jobref LIKE '%sales%' OR
    a.jobemail LIKE '%sales%' OR
    a.jobsalrange LIKE '%sales%' OR
    b.catname LIKE '%sales%'
34
santanu

Für ein einzelnes Schlüsselwort in VARCHAR-Feldern können Sie LIKE verwenden:

SELECT id, category, location
FROM table
WHERE
(
    category LIKE '%keyword%'
    OR location LIKE '%keyword%'
)

Für eine Beschreibung sollten Sie normalerweise einen Volltextindex hinzufügen und eine Volltextsuche (nur MyISAM) ausführen:

SELECT id, description
FROM table
WHERE MATCH (description) AGAINST('keyword1 keyword2')
53
Greg
SELECT 
    *
FROM 
    yourtable
WHERE 
    id LIKE '%keyword%' 
    OR position LIKE '%keyword%'
    OR category LIKE '%keyword%'
    OR location LIKE '%keyword%'
    OR description LIKE '%keyword%'
    OR refno LIKE '%keyword%';
7
Jon Bright

Im Idealfall sollten Sie eine Keyword-Tabelle mit folgenden Feldern erstellen:

Keyword
Id
Count (possibly)

mit einem Index auf Keyword. Erstellen Sie einen Einfüge-/Aktualisierungs-/Lösch-Trigger für die andere Tabelle, sodass bei einer Änderung einer Zeile jedes Schlüsselwort extrahiert und in diese Tabelle eingefügt (oder ersetzt) ​​wird.

Sie benötigen auch eine Worttabelle, um nicht als Schlüsselwörter zu zählen (wenn, und, so, aber, ...).

Auf diese Weise erhalten Sie die beste Geschwindigkeit für Abfragen, die nach Schlüsselwörtern suchen möchten, und können (relativ einfach) komplexere Abfragen wie "enthält Java und RCA1802") implementieren.

"LIKE" Abfragen funktionieren, aber sie werden nicht so gut skaliert.

6
paxdiablo

Eine andere einfachere Option in einem Thread finden Sie hier: Match Against .. mit einer detaillierteren Hilfe in 11.9.2. Boolean Full-Text Searches

Dies ist nur für den Fall, dass jemand eine kompaktere Option benötigt. Dazu muss ein Index FULLTEXT in der Tabelle erstellt werden, was auf einfache Weise erreicht werden kann.

Informationen zum Erstellen von Indizes (MySQL): MySQL FULLTEXT Indexing and Searching

Im FULLTEXT -Index können mehrere Spalten aufgelistet sein. Das Ergebnis wäre eine SQL-Anweisung mit einem Index mit dem Namen search:

SELECT *,MATCH (`column`) AGAINST('+keyword1* +keyword2* +keyword3*') as relevance  FROM `documents`USE INDEX(search) WHERE MATCH (`column`) AGAINST('+keyword1* +keyword2* +keyword3*' IN BOOLEAN MODE) ORDER BY relevance;

Ich habe es mit mehreren Spalten versucht, ohne Glück. Obwohl in Indizes mehrere Spalten zulässig sind, benötigen Sie für jede Spalte einen Index, der mit Match/Against Statement verwendet werden kann.

Abhängig von Ihren Kriterien können Sie eine der beiden Optionen verwenden.

5
raphie

Persönlich würde ich den Zeichenfolgenvergleich LIKE nicht für das ID-Feld oder ein anderes numerisches Feld verwenden. Es macht keinen Sinn nach ID # zu suchen. "216"um 16 zurückzugeben21621651, 3216087, 5321668 ... und so weiter und so fort; ebenfalls mit Gehalt.

Wenn Sie vorbereitete Anweisungen verwenden möchten, um SQL-Injektionen zu verhindern, verwenden Sie eine Abfragezeichenfolge wie die folgende:

SELECT * FROM job WHERE `position` LIKE CONCAT('%', ? ,'%') OR ...
5
Calvin

Ich erkläre die Methode, die ich normalerweise bevorzuge:

Zuallererst müssen Sie berücksichtigen, dass Sie bei dieser Methode den Speicher opfern, um die Rechengeschwindigkeit zu erhöhen. Zweitens müssen Sie das Recht haben, die Tabellenstruktur zu bearbeiten.

1) Fügen Sie ein Feld hinzu (ich nenne es normalerweise "Digest"), in dem Sie alle Daten aus der Tabelle speichern.

Das Feld sieht folgendermaßen aus:

"n-n1-n2-n3-n4-n5-n6-n7-n8-n9" usw. wobei n ein einzelnes Wort ist

Ich erreiche dies mit einem regulären Ausdruck, der "" durch "-" ersetzt. Dieses Feld ist das Ergebnis aller "verdauten" Tabellendaten in einer einzigen Zeichenfolge.

2) Verwenden Sie die LIKE-Anweisung% keyword% im Digest-Feld:

SELECT * FROM table WHERE digest LIKE %keyword%

sie können sogar eine qUery mit einer kleinen Schleife erstellen, sodass Sie nach mehreren Stichwörtern gleichzeitig suchen können, die wie folgt aussehen:

SELECT * FROM table WHERE 
 digest LIKE %keyword1% AND 
 digest LIKE %keyword2% AND 
 digest LIKE %keyword3% ... 
4

Ich weiß, das ist ein bisschen spät, aber was ich mit unserer Bewerbung gemacht habe, ist dies. Hoffe das wird jemandem helfen. Aber es funktioniert bei mir:

SELECT * FROM `landmarks` WHERE `landmark_name` OR `landmark_description` OR `landmark_address` LIKE '%keyword'
OR `landmark_name` OR `landmark_description` OR `landmark_address` LIKE 'keyword%' 
OR `landmark_name` OR `landmark_description` OR `landmark_address` LIKE '%keyword%'
1
AndroidNewbie