2

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これらの結果を からの抜粋とともに表示して、一致が発生した場所を示したいと思います。1 つの単語しかないexcerpt(content, @query)場合でも、正確に必要なものを取得するために呼び出すことができますが、完全一致のみを処理するため、次の場合:@queryexcerpt()

@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'>]

thenexcerpt(content, @query)は nil です。'car contentfast' という正確なフレーズがどこにも現れないからです。

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 を使用する場合、検索結果からの抜粋をどのように表示するのでしょうか?

4

4 に答える 4

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で自動化したいものです。ただ、まだ深く掘り下げる時間がありませんでした。

于 2012-10-13T18:42:12.193 に答える
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。完全に正しいとは言えませんが、機能しているようです。

于 2013-01-15T22:47:02.913 に答える
0

文字列を補間すると、SQL インジェクション攻撃の対象になります。

は dos ( ).selectのようなパラメーター化されたステートメントを受け入れないため、明示的にサニタイズする必要があります。.whereUsers.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"])
于 2015-08-19T22:19:51.003 に答える