GINインデックス付きTSVECTOR列から部分一致を取得します


13

これをクエリして結果を取得したい:

SELECT * FROM (
  SELECT id, subject
  FROM mailboxes
  WHERE tsv @@ plainto_tsquery('avail')
) AS t1 ORDER by id DESC;

これは機能し、をtsv含む行を返しますAvailable。しかし、私が使用avai(ドロップlable)した場合、何も見つかりません。

すべてのクエリは辞書にある必要がありますか?このような文字だけを照会することはできませんか?電子メールの本文(コンテンツ)を含むデータベースがあり、毎秒成長するにつれて高速にしたいと思います。現在使用しています

... WHERE content ~* 'letters`

回答:


22

すべてのクエリは辞書にある必要がありますか?

いいえ。最初に使用されるテキスト検索構成に応じて、単語の語幹のみがインデックスに含まれているためです。しかし、もっと重要なのは:

いいえ。なぜなら、その上で全文検索プレフィックス一致可能だからです

これはうまくいくでしょう:

SELECT id, subject
FROM   mailboxes
WHERE  tsv @@ to_tsquery('simple', 'avail:*')
ORDER  BY id DESC;

3つのことに注意してください。

  1. この場合to_tsquery()、ではなくを使用しますplainto_tsquery()マニュアルを引用):

    ... 入力の演算子、重みラベル、またはプレフィックス一致ラベルをplainto_tsquery認識しませんtsquery

  2. 'simple'テキスト検索構成を使用してを生成しtsqueryます。明らかに「avail」という単語をそのまま使用し、ステミングを適用しないためです。

  3. 追加:*それプレフィックス検索にする、すなわち「無駄」で始まるすべての語彙素を見つけます。

重要:これは、ドキュメント内の語彙素(語幹)のプレフィックス検索です。ワイルドカード(content ~* 'avail')なしの正規表現一致は、まったく同じではありません!後者は(語彙素の開始まで)左アンカーではなく、「FOOavail」なども見つかります。

クエリで説明されている動作が必要か、追加された正規表現に相当する動作が必要かは不明です。すでに提案されている@Evanのpg_trgmようなトライグラムインデックス()は、そのための適切なツールです。dba.SEには多くの関連する質問があります検索してみてください

概要:

デモ

SELECT *
FROM (
   VALUES
     ('Zend has no framework')
   , ('Zend Framework')
   ) sub(t), to_tsvector(t) AS tsv
WHERE tsv @@ to_tsquery('zend <-> fram:*');
 id |       t        |          tsv
----+----------------+------------------------
  2 | Zend Framework | 'framework':2 'zend':1

最近の関連する回答(検索を最適化するための別のアプローチの章):

メール?

電子メールに言及したので、テキスト検索パーサーは電子メールを識別し、それらを個別の単語/語彙素に分割しないことに注意してください。考慮してください:

SELECT ts_debug('english', 'xangr@some.domain.com')
(email,"Email address",xangr@some.domain.com,{simple},simple,{xangr@some.domain.com})

セパレーター@.メールのスペースをスペース(' ')に置き換えて、含まれている単語のインデックスを作成します。

また、英語(または他の言語)の単語ではなく、メールで名前を処理しているため、テキスト検索構成を使用して、ステミングおよびその他の言語機能を無効にします。'simple'

次を使用してts_vector列を作成します。

SELECT to_tsvector('simple', translate('joe.xangr@some.domain.com', '@.', '  ')) AS tsv;

私はこれが初めてだと明らかに間違っており、それを思い出したくないので、どちらの方法でも私の答えを削除しています。私はあなたのために2つの質問があります1):*文書化されている場所、および2)to_tsvector('simple'..)そのtsvの将来のクエリがtsqueryにも「単純な」構成を必要とするという指示と一緒にビルドに関する言及はありませんか?tsvector / tsqueryでステミングを無効にすることの影響を明確にする必要があると思います。
エヴァンキャロル

@EvanCarroll:「単純な」構成を使用する必要はありませ。それは、ステミング(「ラット」から「ラット」など)を避けるだけです。与えられた例には望ましくありません。マニュアル:上記のリンクを追加しました...
Erwin Brandstetter

4
@EvanCarroll:余談:あなたが初めて間違っていると思うのは二度目でしょう。そして、それは再帰的に間違っているでしょう。;)
アーウィンブランドステッター

2
@ErwinBrandstetter、うわー、あなたの方法はちょうど私に全速検索を与えました。あなたの方法の前にそれ0.380msは結果を得るのにかかりました。あなたの方法の後、それはかかりました0.079 ms
xangr 16

1
@xangr:いいえ、FTS は語彙素のプレフィックス一致のみを提供します。その他については、をご覧くださいpg_trgm。FTSは高速です(より小さいインデックスを使用)。両方のインデックスを組み合わせることもできます...
Erwin Brandstetter
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.