2010-01-21 45 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