2008-12-28 9 views
6

Ich mache eine Suchfunktion für meine Website, die relevante Ergebnisse aus einer Datenbank findet. Ich suche nach einer Möglichkeit, Vorkommnisse eines Wortes zu zählen, aber ich muss sicherstellen, dass es Wortgrenzen auf beiden Seiten des Wortes gibt (damit ich nicht mit "dreifach" enden kann, wenn ich "rippen" möchte).Zählvorkommen eines Wortes in einer Reihe in MySQL

Hat jemand irgendwelche Ideen?

Wie kann ich die Zahl solcher Vorkommnisse innerhalb einer einzigen Reihe zählen:


Menschen meine Frage haben falsch verstanden?

Antwort

2

Dies ist nicht der Fall, in dem relationale Datenbanken sehr gut sind, es sei denn, Sie können Volltextindizierung verwenden, und Sie haben bereits festgestellt, dass Sie dies nicht können, da Sie InnoDB verwenden. Ich würde vorschlagen, dass Sie Ihre relevanten Zeilen auswählen und die Wortzählung in Ihrem Anwendungscode ausführen.

0

So etwas sollte funktionieren:

select count (*) aus der Tabelle, wo Feldname REGEXP '[[: <:]] Wort [[:>:]]';

Die genauen Details finden Sie im MySQL-Handbuch, Abschnitt 11.4.2.

+2

, wie viele Zeilen den Suchtext enthalten. Der Fragesteller möchte zählen, wie oft der Suchstring in jeder Zeile enthalten ist. – flu

0

So etwas wie LIKE oder REGEXP wird nicht skaliert (es sei denn, es ist eine Übereinstimmung am äußersten linken Präfix).

Betrachten Sie stattdessen eine fulltext index für was Sie tun möchten.

select count(*) from yourtable where match(title, body) against ('some_word'); 
+0

Volltextindex kann nicht ausgeführt werden ... Ich verwende InnoDB. – stalepretzel

0

Ich habe die Technik wie im folgenden Link beschrieben verwendet. Die Methode verwendet length und replace Funktionen von MySQL.

Keyword Relevance

1

Sie diese perverse Art und Weise versuchen:

SELECT 
(LENGTH(field) - LENGTH(REPLACE(field, 'word', '')))/LENGTH('word') AS `count` 
ORDER BY `count` DESC 
  • Diese Abfrage kann sehr langsam sein
  • Es sieht ziemlich hässlich
  • REPLACE() ist case-sensitive
+0

Dies zählt * Strings *, nicht * Wörter *. – RandomSeed

1

Sie können das Problem der mysql-REPLACE()-Funktion mit LOWER() umgehen.

Es ist schlampig, aber an meinem Ende läuft diese Abfrage ziemlich schnell.

Um Dinge schneller zu machen, erhalte ich die Ergebnismenge in einer Auswahl, die ich in meiner 'äußeren' Abfrage als abgeleitete Tabelle deklariert habe. Da mysql zu diesem Zeitpunkt bereits die Ergebnisse liefert, funktioniert die Methode replace ziemlich schnell.

Ich habe eine Abfrage ähnlich der folgenden erstellt, um nach mehreren Begriffen in mehreren Tabellen und mehreren Spalten zu suchen.Ich erhalte eine ‚Relevanz‘ Zahl entspricht die Summe der Anzahl aller occurrances aller gefundenen Suchbegriffe in allen Spalten

SELECT DISTINCT ( 
((length(x.ent_title) - length(replace(LOWER(x.ent_title),LOWER('there'),'')))/length('there')) 
+ ((length(x.ent_content) - length(replace(LOWER(x.ent_content),LOWER('there'),'')))/length('there')) 
+ ((length(x.ent_title) - length(replace(LOWER(x.ent_title),LOWER('another'),'')))/length('another')) 
+ ((length(x.ent_content) - length(replace(LOWER(x.ent_content),LOWER('another'),'')))/length('another')) 
) as relevance, 
x.ent_type, 
x.ent_id, 
x.this_id as anchor, 
page.page_name 
FROM ( 
(SELECT 
'Foo' as ent_type, 
sp.sp_id as ent_id, 
sp.page_id as this_id, 
sp.title as ent_title, 
sp.content as ent_content, 
sp.page_id as page_id 
FROM sp 
WHERE (sp.title LIKE '%there%' OR sp.content LIKE '%there%' OR sp.title LIKE '%another%' OR sp.content LIKE '%another%') AND (sp_content.title NOT LIKE '%goes%' AND sp_content.content NOT LIKE '%goes%') 
) UNION (
    [search a different table here.....] 
) 
) as x 
JOIN page ON page.page_id = x.page_id 
WHERE page.rstatus = 'ACTIVE' 
ORDER BY relevance DESC, ent_title; 

Hoffnung gesucht, das hilft jemand

- Seacrest aus

+0

Dies zählt * Strings *, nicht * Wörter *. – RandomSeed

-3

Es hängt davon ab, welches DBMS Sie verwenden, einige erlauben das Schreiben von UDFs, die dies tun können.

0

Wenn Sie eine Suche möchten, würde ich etwas wie Sphinx oder Lucene empfehlen, ich finde Sphinx (als unabhängiger Volltext-Indexer) viel einfacher einzurichten und zu laufen. Es läuft schnell und generiert die Indizes sehr schnell. Selbst wenn Sie MyISAM verwenden würden, würde ich vorschlagen, es zu verwenden, es hat viel mehr Macht als ein Volltextindex von MyISAM.

Es kann auch (etwas) mit MySQL integrieren.

1

eine benutzerdefinierte Funktion wie diese erstellen und es in Ihrer Anfrage

DELIMITER $$ 

CREATE FUNCTION `getCount`(myStr VARCHAR(1000), myword VARCHAR(100)) 
    RETURNS INT 
    BEGIN 
    DECLARE cnt INT DEFAULT 0; 
    DECLARE result INT DEFAULT 1; 

    WHILE (result > 0) DO 
    SET result = INSTR(myStr, myword); 
    IF(result > 0) THEN 
     SET cnt = cnt + 1; 
     SET myStr = SUBSTRING(myStr, result + LENGTH(myword)); 
    END IF; 
    END WHILE; 
    RETURN cnt;  

    END$$ 

DELIMITER ; 

es hilft, diese Kontrollen Hoffnung verwenden Refer This

Verwandte Themen