1

私は約150万レコードのPostgresデータベースを持っています。私のRuby on Railsアプリケーションでは、statement_textフィールド(1〜数百の単語を含むことができる)を検索する必要があります。Postgresのフルテキスト検索を使用して完全一致を検索する最良の方法は何ですか?

私の問題:私は、私はsearch_all_wordsまたはsearch_any_wordsのようなスコープを作成するためにpgSearch宝石を使用することができます知っているが、私は結果セットに返され完全一致持つレコードだけを確保するための最も効率的な方法は何か不確かです。

つまり、私が「Pope Francis」を検索すると、連続して同じ順序で(「The pope is Francis」とは反対の)2つの単語しか見つからないようにしたい。

これまでのところ、完全一致検索ではGINインデックスとILIKEを組み合わせただけです。しかし、GIN指数が本質的にすべてのレコードでstoring the exact position of a wordによって働いているとすれば、検索用語がフィールドと完全に一致することを確実にするより効率的な方法はありませんか?

答えて

1

は、一般的に言って、フルテキスト検索を使用すると、あなたが探しているフレーズの関連性を決定するためにを生じることなく、かつ'simple'辞書ts_rank()機能を使用することができるとして、フルテキストは、使用言語辞書に基づいて派生語を必要とし。

WITH t(v) AS (VALUES 
    ('Test sentence with Pope Francis'), 
    ('Test Francis sentence with Pope '), 
    ('The pope is named Francis') 
) 
SELECT v,ts_rank(tsv,q) as rank 
FROM t, 
    to_tsvector('simple',v) as tsv, 
    plainto_tsquery('simple','Pope Francis') AS q; 

結果:フルテキスト検索なし

   v     | rank  
----------------------------------+----------- 
Test sentence with Pope Francis | 0.0991032 
Test Francis sentence with Pope | 0.0973585 
The pope is named Francis  | 0.0973585 
(3 rows) 

、あなたはpg_trgm拡張子とのマッチングだけ速くILIKEパターンを実装することができます。例はhereです。

+0

ありがとう、ドミトリー!私は全文検索を使っているので、ts_rankを使うことができます。しかし問題は、フィールドの語数によっては、ILIKEを使用せずに、単語が隣接して正しい順序で確実に特定されることではありません。私はそれを正しく理解していますか? – jayp

+0

いいえ、長さに基づいてカットオフはありません。フレーズに一致するものがある場合、それはまだ高いランクを持ちます。 ts_rankの正規化係数を省略することもできます。正常に動作するはずです。 –

+0

OK、ありがとうございます! – jayp

関連する問題