ホームページ >ウェブフロントエンド >jsチュートリアル >PostgreSQL 全文検索の位置別ランク
最近、全文検索で問題が発生しました。私は検索入力でこの機能を使用しており、入力時にバックエンドが一致する可能性のあるヒントを送信します。バックエンドデータベースはPostgreSQLです。テキスト内の検索語の位置によってヒントをランク付けする必要がありました。
そのため、「スター ウォーズ」のタイトルを検索すると、「スター ウォーズ 7 ~ 9 がスター ウォーズの世界をどう変えたか (スター ウォーズに関する楽しいドキュメンタリー)」ではなく、「スター ウォーズ」の投稿が最初に表示されます。期間が3回あるほど上位にランクされます。
PostgreSQL での全文検索は非常に簡単に実現できます。使用する主なツールは 2 つあります:
ブログ投稿のタイトルを検索したいとします。それらを検索可能にするには、次のクエリを使用できます:
SELECT id, title FROM blogposts WHERE to_tsquery('JavaScript') @@ to_tsvector(posts.title);
この場合、検索ごとに投稿タイトルを動的に tsvector に変換しています。ただし、この変換には時間がかかります。より良いアプローチは、この変換をデータベース内で事前に実行し、それをタイトルのインデックスとして保存して、検索を高速化することです。
タイトルのベクトルの新しい列を作成し、この新しい列にインデックスを付けましょう:
ALTER TABLE blogposts ADD COLUMN search_vector tsvector; UPDATE blogposts SET search_vector = (to_tsvector(posts.title)); CREATE INDEX titles_fts_idx ON blogposts USING gin(search_vector);
次に、「JavaScript」という用語を検索してみてください
SELECT id, title FROM blogposts WHERE to_tsquery('JavaScript') @@ search_vector;
次のように、ts ベクトルから直接タイトル列にインデックスを作成することもできます。
CREATE INDEX titles_fts_idx ON blogposts USING GIN (to_tsvector(posts.title));
次のように検索を使用します:
SELECT id, title FROM blogposts WHERE to_tsquery('JavaScript') @@ posts.title;
全文検索が非常に高速になり、数ミリ秒で完了します。
PostgreSQL には ts_rank 機能があり、検索結果にスコアを付け、ランキングに基づいて並べ替えることができます。 PostgreSQL は次のランキング オプションをサポートしています:
ts_rank は次のように使用できます:
SELECT ... ts_rank(search_vector, to_tsquery('JavaScript'), 0) as rank_title ... ORDER BY rank_title DESC NULLS LAST
ただし、文字列 (タイトル列など) 内の検索語の位置に基づく組み込みのランキング オプションはありません。
幸いなことに、PostgreSQL には POSITION 関数があります。 PostgreSQL POSITION 関数は、指定された文字列内の部分文字列の位置を見つけるために使用されます。私たちの場合、次のように使用できます
SELECT id, title FROM blogposts WHERE to_tsquery('JavaScript') @@ to_tsvector(posts.title);
ts_rank は正規化整数 2 を使用します。2 はランクをドキュメントの長さで割るためです。
マジックナンバー 0.0001 は、POSTION 関数が 0 ではなく 1 からカウントし、文字列が見つからない場合は 0 を返すため、0 による除算を避けるためのものです。
最終的なコードは次のようになります:
ALTER TABLE blogposts ADD COLUMN search_vector tsvector; UPDATE blogposts SET search_vector = (to_tsvector(posts.title)); CREATE INDEX titles_fts_idx ON blogposts USING gin(search_vector);
一度に複数の用語を検索する場合は、1 つの注意点があります (JavaScript や TypeScript など)。
to_tsquery 関数の引数は、論理演算子などを含め、非常に柔軟に使用できます。一方、POSITION 関数は文字列内の「単なる」部分文字列です。
これは、postgres (SQL) npm ライブラリを使用する SvelteKit Web アプリケーションの実際のエンドポイントからの私の例です:
SELECT id, title FROM blogposts WHERE to_tsquery('JavaScript') @@ search_vector;
問題のドキュメントへのリンクは次のとおりです:
以上がPostgreSQL 全文検索の位置別ランクの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。