2011-05-29 67 views
3

我有一個MySQL名爲InnoDB的表,其中包含'name'列(VARCHAR(255)),我希望用戶能夠搜索該列,並返回所有匹配的行。但是,我不能只使用LIKE查詢,因爲搜索需要允許用戶鍵入與可用名稱相似的名稱(例如,用'The'作爲前綴,或者不知道正確的名稱包含撇號)。使用模糊匹配搜索單個MySQL文本列

兩個例子是:

在DB名稱:「玫瑰和皇冠」

例可能的搜索結果應符合:「玫瑰&皇冠」,「玫瑰和皇冠」,「玫瑰和皇冠」, 「玫瑰和皇冠」

名稱在DB:「潛水員酒店」

例可能的搜索結果應符合:「潛水員」客棧」,‘潛水員的酒店’,‘潛水酒店’

我也希望能夠通過「最接近的匹配」相關性對結果進行排名,儘管我不確定這將如何完成(編輯距離也許?)。

這個表不可能長到幾千行,所以一個不能伸縮到數百萬行的方法是好的。一旦輸入,給定行的名稱值不會改變,所以如果需要昂貴的索引操作,這不成問題。

是否有現成的工具可以執行此任務?我看了Zend_Search_Lucence,但似乎專注於文檔,而我只在搜索單個列時感興趣。

編輯:在SOUNDEX搜索,這不會產生我想要的結果。例如:

SELECT soundex('the rose & crown') AS soundex1, soundex('rose and crown') AS soundex2; 
soundex1 soundex2 
T6265 R253265 

解決方法:在最後我用Zend_Search_Lucence,只是假裝每名實際上是一個文件,這似乎達到我想要的結果。我想這是全文搜索的方式,即使每個字符串最多隻有3-4個字。

+0

或許** **的Soundex算法將適合你案例:http://en.wikipedia.org/wiki/Soundex – 2011-05-29 16:31:42

+0

MySQL'SOUNDEX()'函數:http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_s oundex – 2011-05-29 16:32:24

+0

或者Damerau-Levenshtein距離算法:http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance – 2011-05-29 16:38:06

回答

3

全文搜索(FTS)是您希望的數據庫功能的術語。有:

+0

本機MySQL支持不起作用 - 正如我在問題中所說的,我的表是InnoDB。另外,用戶不會將他們的查詢指定爲'Rose','Crown',它將是'Rose&Crown'(例如)。 – pwaring 2011-05-29 16:46:22

+0

@pwaring:這就是我提到第三方支持的原因。瞭解通用術語應該使查找更多信息變得更容易。 – 2011-05-29 16:48:21

1

這是一個非常接近你想要的SO問題。雖然答案是PHP和MySQL,總的原則仍然適用:

How do I do a fuzzy match of company names in MYSQL with PHP for auto-complete?

基本上你會使用SOUNDEX得到你想要的東西。如果您需要更多的功率,長字符串,等等。你可能想看看雙音位,這是超過音位的改善和探測:

http://aspell.net/metaphone/

http://www.atomodo.com/code/double-metaphone

+1

SOUNDEX的缺點對我來說似乎有點太大 - 特別是第一個字母是相同的('玫瑰和皇冠'和'玫瑰和皇冠'沒有相同的第一個字母)。 – pwaring 2011-05-29 16:45:48

+0

@pwaring:你可以繞過那些小的常見單詞,如'a','和'''',還有撇號,引號,逗號等,然後使用Soundex。 – 2011-05-29 16:55:59

+0

我可以做,但這需要編寫代碼來去除常用詞,標點符號等,但我真的想說「這裏是用戶的查詢,按照此列搜索並返回按相關性排序的結果」。如果我不得不從查詢中刪除東西,你可以保證我會錯過一些東西。 :) – pwaring 2011-05-29 16:59:58