2012-06-21 33 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