2008-12-28 60 views
6

我正在爲我的網站製作搜索功能,該功能從數據庫中查找相關結果。我正在尋找一種方法來統計單詞的出現次數,但我需要確保單詞的兩側都有單詞邊界(所以當我想要「翻錄」時,我不會以「三重」結尾)。統計在MySQL中連續出現的單詞

有沒有人有任何想法?


人們誤解了我的問題:

我怎麼能算一單排內,OCCURENCES 的數量?

回答

2

這不是關係數據庫非常擅長的事情,除非你可以使用全文索引,並且你已經聲明你不能,因爲你使用的是InnoDB。我建議選擇你的相關行並在應用程序代碼中進行單詞計數。

0

像這樣應該工作:

SELECT COUNT(*)從表,其中字段名REGEXP '[[:<:]]字[[:>:]]';

血淋淋的細節在MySQL手冊的第11.4.2節中。

+2

此檢查有多少行包含搜索字符串。提問者想要計算每行中搜索字符串的頻率。 – flu 2014-01-20 15:19:19

0

像LIKE或REGEXP這樣的東西不會縮放(除非它是最左邊的前綴匹配)。

請考慮改爲使用fulltext index來執行您想要的操作。

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

不能做全文索引...我正在使用InnoDB。 – stalepretzel 2008-12-28 19:53:05

0

我已經使用了以下鏈接中描述的技術。該方法使用MySQL的lengthreplace函數。

Keyword Relevance

1

你可以試試這個變態的辦法:

SELECT 
(LENGTH(field) - LENGTH(REPLACE(field, 'word', '')))/LENGTH('word') AS `count` 
ORDER BY `count` DESC 
  • 此查詢可以是非常慢
  • 它看起來很醜陋
  • REPLACE()是區分大小寫的
+0

這會計算* strings *,而不是* words *。 – RandomSeed 2014-06-12 19:03:43

1

您可以通過使用LOWER()來解決mysql區分大小寫REPLACE()函數的問題。

它馬虎,但在我的結束這個查詢運行速度非常快。

爲了加快速度,我在我的'外部'查詢中聲明爲派生表的select中檢索結果集。由於mysql在這一點上已經有了結果,所以replace方法工作得很快。

我創建了一個類似於下面的查詢來在多個表格和多列中搜索多個術語。我獲得「相關性」等同於所有列所有找到的搜索項的所有occurrances的計數和數搜索

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; 

希望這可以幫助別人

- 西克雷斯特出

+0

這將計數*字符串*,而不是*字*。 – RandomSeed 2014-06-12 19:03:27

-3

它取決於你正在使用的DBMS,有些允許編寫可以做到這一點的UDF。

0

如果你想要搜索,我會建議像Sphinx或Lucene這樣的東西,我發現Sphinx(作爲一個獨立的全文索引器)可以更容易地設置和運行。它運行速度快,並且生成索引速度非常快。即使你使用的是MyISAM,我也會建議使用它,但它比MyISAM的全文索引有更多的功能。

它也可以整合(有點)與MySQL。

1

創建用戶定義的函數像這樣在您的查詢中使用它

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 ; 

希望它可以幫助 Refer This