我在Heroku上的Rails应用程序中设置了pg_search:
@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()
仅处理完全匹配,因此如果:{/ p>
@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
中没有任何地方出现确切的短片'car fast'。
我认为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时,人们如何显示搜索结果的摘录?
答案 0 :(得分: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中自动生成的东西。我还没有时间深入研究它。
答案 1 :(得分: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
调用的{{1}}个参数 - 我确信这不是完全合理的,但似乎有效。
答案 2 :(得分: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"])
答案 3 :(得分:0)
有一种更简单的方法,如果你不想通过SQL挖掘 - 你可以利用内置的pg_search gem功能以一种非常简单直接的方式显示摘录:
在您的控制器中:
@articles = Article.search(params[:search]).with_pg_search_highlight
在您看来:
= raw(article.pg_search_highlight)
应该这样做。