19

この回答に続いて、ランクで並べ替え、一致するクエリのみ制限する場合、PostgreSQL の組み込みの全文検索を使用する最良の方法を知りたいと思います。

非常に単純なテーブルを想定してみましょう。

CREATE TABLE pictures (
  id SERIAL PRIMARY KEY,
  title varchar(300),
  ...
)

または何でも。今、私はフィールドを検索したいと思いtitleます。まず、インデックスを作成します。

CREATE INDEX pictures_title ON pictures 
  USING gin(to_tsvector('english', title));

今、私は検索したい'small dog'。これは機能します:

SELECT pictures.id, 
       ts_rank_cd(
         to_tsvector('english', pictures.title), 'small dog'
       ) AS score
FROM pictures
ORDER BY score DESC

しかし、私が本当に欲しいのはこれです:

SELECT pictures.id, 
       ts_rank_cd(
         to_tsvector('english', pictures.title), to_tsquery('small dog')
       ) AS score
FROM pictures 
WHERE to_tsvector('english', pictures.title) @@ to_tsquery('small dog')
ORDER BY score DESC

または、これ(これは機能しません-句scoreでは使用できません):WHERE

SELECT pictures.id, 
       ts_rank_cd(
         to_tsvector('english', pictures.title), to_tsquery('small dog')
       ) AS score
FROM pictures WHERE score > 0
ORDER BY score DESC

これを行う最善の方法は何ですか?私の質問は何倍もあります:

  1. バージョンを繰り返し使用するto_tsvector(...)と、それが 2 回呼び出されますか、それとも何らかの方法で結果をキャッシュするのに十分なほどスマートですか?
  2. to_ts...関数呼び出しを繰り返さずにそれを行う方法はありますか?
  3. 句で使用する方法はscoreまったくありますか?WHERE
  4. もしあれば、それでフィルタリングするscore > 0か、それを使用する方が良いでしょ@@うか?
4

3 に答える 3

6
select *
from (
    SELECT
        pictures.id,
        ts_rank_cd(to_tsvector('english', pictures.title), 
        to_tsquery('small dog')) AS score
    FROM pictures
) s
WHERE score > 0
ORDER BY score DESC
于 2012-10-17T12:18:53.690 に答える
4

to_tsvector(...) を繰り返し使用するバージョンを使用すると、それが 2 回呼び出されますか、それとも何らかの方法で結果をキャッシュするのに十分スマートですか?

これらのことに気付く最善の方法は、簡単な説明をすることですが、それらは読みにくい場合があります。

簡単に言うと、PostgreSQL は計算結果を再利用できるほどスマートです。

to_ts... 関数呼び出しを繰り返さずにそれを行う方法はありますか?

私が通常行うことtsvは、テキスト検索ベクトルである列を追加することです。トリガーを使用してこの自動更新を行うと、すぐにベクトルに簡単にアクセスできるようになりますが、トリガーを選択的にすることで検索インデックスを選択的に更新することもできます。

WHERE 句でスコアを使用する方法はありますか?

はい、しかしその名前ではありません。または、サブクエリを作成することもできますが、個人的にはそれを繰り返します。

ある場合、スコア > 0 でフィルタリングするか、@@ を使用する方がよいでしょうか?

私が考えることができる最も単純なバージョンはこれです:

SELECT *
FROM pictures
WHERE 'small dog' @@ text_search_vector

text_search_vector明らかに次のようなものに置き換えることができますto_tsvector('english', pictures.title)

于 2012-10-19T00:57:18.070 に答える