2012-06-21 40 views
2

我已经成立了pg_search在我的Rails应用程序在Heroku:如何显示从PG-搜索multisearch摘录结果

@query = 'fast' 
PgSearch.multisearch(@query) #=> 
[#<PgSearch::Document searchable: ferrari, :content: 'this car is really fast'>, 
#<PgSearch::Document searchable: viper, :content: 'a very fast car'>] 

我想显示这些结果与content摘录,以显示其中匹配发生。我可以打电话excerpt(content, @query)得到我想要的东西时@query仅一字之差,但excerpt()只能处理精确匹配,因此,如果:

@query = 'car fast' 
PgSearch.multisearch(@query) #=> 
[#<PgSearch::Document searchable: ferrari, :content: 'this car is really fast'>, 
#<PgSearch::Document searchable: viper, :content: 'a very fast car'>] 

然后excerpt(content, @query)是零,因为无处content不准确的那句“汽车快”出现。

我认为excerpt(content, @query.split(' ').first)至少显示东西进行多字查询,但仍存在这样的情况下:

@query = 'car?' 
@results = PgSearch.multisearch(@query) #=> 
[#<PgSearch::Document searchable: ferrari, :content: 'this car is really fast'>, 
#<PgSearch::Document searchable: viper, :content: 'a very fast car'>] 
excerpt(@results.first.content, @query) #=> nil 

那么,如何乡亲使用pg_search时显示在搜索结果中摘录?

回答

1

FWIW-按照上面nertzy的例子,我能得到这个具有以下工作:

PgSearch.multisearch(@query).select("ts_headline(pg_search_documents.content, plainto_tsquery('english', ''' ' || unaccent('#{@query}') || ' ''' || ':*')) AS excerpt") 

我遇到了麻烦plainto_tsquery(?)的工作,因为它是抛出一个语法错误。以上我的解决办法是简单地做

PgSearch.multisearch(@query).select(["ts_headline(pg_search_documents.content, plainto_tsquery(?)) AS excerpt", @query]).to_sql 

然后在to_tsquery参数堵漏新plainto_tsquery呼叫东西​​,我敢肯定的结果是不完全的声音,但似乎工作。

+0

第一块代码适用于我。感谢Sirvine的回答,并感谢Nertzy为我们指出了正确的方向和出色的pg_search gem! –

+1

是不是第一个代码块受SQL注入? – bfcoder

2

我是pg_search的作者和维护者。

现在还没有一个内置的方式来获得摘录沿侧你的结果在pg_search,但也有可能很容易,如果我或其他人有建造起来的时间。

PostgreSQL有函数ts_headline,您可以调用它作为列返回字符串摘录。

可能可以调用这样的事情(我没有测试它尚未):

PgSearch.multisearch(@query).select(["ts_headline(pg_search_documents.content, plainto_tsquery(?)) AS excerpt", @query]) 

然后每个结果都应该有一个excerpt方法返回像你想要什么。

顺便说一下,这是我最终想在pg_search中自动生成的。我只是没有时间深入研究它。

0

如果插入字符串,您将受到SQL注入攻击。

由于.select不会接受像.where这样的参数化语句(Users.where("id = ?", params[:id])),因此您需要明确进行清理。

sanitized = ActionController::Base.helpers.sanitize(params[:q]) 
@results = PgSearch.multisearch(params[:q]) 
        .select(["ts_headline(pg_search_documents.content, plainto_tsquery('english', ''' ' || '#{sanitized}' || ' ''' || ':*')) AS excerpt"]) 
0

有一个更简单的方法,如果你不喜欢通过SQL挖 - 你可以利用内置的pg_search宝石的功能在一个非常简单和直接的方式来显示摘录:

在控制器:

@articles = Article.search(params[:search]).with_pg_search_highlight 

在你看来:

= raw(article.pg_search_highlight) 

那SH应该这样做。

+0

这不适用于multisearch,因为指定的问题。 – thewoolleyman