2010-01-21 67 views
0

我想更多的返回結果像搜索Rails的:一個好的搜索算法

我CURREN算法是這樣的

def search_conditions(column, q) 
    vars = [] 
    vars2 = [] 

    vars << q 

    if q.size > 3 
    (q.size-2).times do |i| 
     vars2 << q[i..(i+2)] 
     next if i == 0 
     vars << q[i..-1] 
     vars << q[0..(q.size-1-i)] 
     vars << q[i % 2 == 0 ? (i/2)..(q.size-(i/2)) : (i/2)..(q.size-1-(i/2))] if i > 1 
    end 
    end 

    query = "#{column} ILIKE ?" 
    vars = (vars+vars2).uniq 

    return [vars.map { query }.join(' OR ')] + vars.map { |x| "%#{x}%" } 
end 

如果我搜索「Ruby on Rails的」它將使搜索4方法。

1)卸下左側字母 「uby on Rails的」 .. 「ILS」

2)卸下右字母 「紅寶石上軌」 .. 「揉搓」

3)卸下左側和右側字母「uby on Rails」,「uby on Rail」...「on」

4)僅使用3個字母「Rub」,「uby」,「by」,「yo」,「on」... 「ils」

很好用這4種方式嗎?還有嗎?

+0

我不完全確定你想要做什麼,但看起來像任何匹配1 - 3的東西也會被4匹配。 – mckeed 2010-01-21 23:34:11

+0

我試圖找到與搜索相似的單詞 – 2010-01-22 00:22:43

+0

類似的意思,或類似的拼寫?如果拼寫真的是你所關心的,我會用@AlexReisner提到的Levenshtein Distance思想。否則,去一個真正的搜索引擎。無論哪種方式,我認爲您不會通過修剪搜索字詞中的前導/後綴字母來獲得非常有利的結果。 – pkaeding 2010-01-22 00:38:10

回答

6

爲什麼要刪除這些字母?你是否試圖確保如果有人搜索'小部件',你也會匹配'小部件'?

如果是這樣,你所要做的就是'stemming',它比刪除前後的字母要複雜得多。您可能也有興趣從您的查詢中刪除'stop words'。這些是非常常見的詞語,它們對於形成語法正確的句子是必要的,但對於搜索沒有多大用處,例如'a','the'等。

獲得搜索權是一個非常複雜和困難的問題。我建議你不要試圖自己解決它,而是專注於你網站的核心目的。也許你可以利用代碼中的Lucene項目的搜索功能。此鏈接可能對using Lucene in Ruby on Rails有幫助。

我希望有幫助;我意識到,我有點側面你的原始問題,但我真的不會建議你自己解決這個問題。

+0

這就是我們所說的好建議。 – jonnii 2010-01-21 23:39:48

+0

solr看起來非常好,我想我會用它。 :) – 2010-01-22 01:05:33

+1

很酷,我很高興它幫助! – pkaeding 2010-01-22 01:28:18

2

正如pkaeding所說,詞幹分析太複雜了,無法實現自己。然而,如果你想在MySQL中搜索類似的(不是精確的)字符串,並且你的用戶搜索條件非常接近數據庫字段的全部值(即,你不是搜索一個單詞的大量文本或短語),你可能想嘗試使用Levenshtein distance。這是一個MySQL implementation

Levenshtein算法將允許您執行「模糊」匹配,爲您提供相似度分數,並幫助您避免安裝和配置搜索守護進程,這很複雜。但是,這隻適用於非常特殊的情況,而不是一般的網站搜索。

+0

這是一個好主意,如果它適合你的目的。我將書籤鏈接:) – pkaeding 2010-01-21 23:49:48

+0

這個算法看起來很有趣,但我認爲它不適用於我的情況。無論如何,書籤。 – 2010-01-22 01:03:57

1

雖然,都表明其他可能的解決方案,請訪問:

Sphinx - 如何實現爲10+百萬行的表的全文搜索,跟上負載,並保持相關性?獅身人面像擅長這些謎語。

Thinking Sphinx - Sphinx和ActiveRecord之間的Ruby連接器。

+0

但獅身人面像會搜索相似的單詞嗎? – 2010-01-22 00:19:54