今後のPostgreSQL 11リリースの興味深い機能のトピックを続けて 、 新しい組み込み関数websearch_to_tsqueryについてお話したいと思います。 対応するパッチは 、Vidor DrobnyとDmitry Ivanovによって開発され、Fedor Sigaevから編集されています。 このパッチに実装されているものを見てみましょう。
全文検索は長い間PostgreSQLで行われてきたようで、非常にうまく機能します。 他に何を追加できますか?
PostgreSQLに基づいてオンラインストアを作成しており、製品で検索する必要があると想像してください。 ここに、検索クエリを含むフォームがあります。 このクエリからデータベースを検索するには、何らかの方法でtsvectorを作成する必要があります。 これは、to_tsquery関数を使用して実行できます。 ただし、to_tsqueryは、文字列が特定の形式であると想定しています。
=# select to_tsquery('foo bar baz');
ERROR: syntax error in tsquery: "foo bar baz"
=# select to_tsquery('foo & bar & baz');
to_tsquery
-----------------------
'foo' & 'bar' & 'baz'
つまり、この場合、ユーザーのクエリを理解可能なto_tsqueryに変換する関数を作成する必要があります。 不便。 一部では、plainto_tsqueryおよびphraseto_tsquery関数がこの問題を解決します。
=# select plainto_tsquery('foo bar baz');
plainto_tsquery
-----------------------
'foo' & 'bar' & 'baz'
=# select phraseto_tsquery('foo bar baz');
phraseto_tsquery
---------------------------
'foo' <-> 'bar' <-> 'baz'
しかし、それらには問題があります。 事実、ユーザーはクォート、またはある種のブール演算子を直感的に使用できます。これは、Google、Yandex、その他の検索エンジンで機能するためです。 この場合に何が起こるか見てみましょう:
=# select plainto_tsquery('"foo bar" -baz or qux');
plainto_tsquery
-------------------------------
'foo' & 'bar' & 'baz' & 'qux'
すべてが壊れています! 痛い。 独自のパーサーを書くことは本当に必要ですか?
PostgreSQL 11以降、アプリケーションごとにゼロから作成する必要がないように、対応するパーサーがDBMSで正しくなります。
=# select websearch_to_tsquery('"foo bar" -baz or qux');
websearch_to_tsquery
----------------------------------
'foo' <-> 'bar' & !'baz' | 'qux'
websearch_to_tsqueryが引用符、マイナス記号、およびブール演算子を理解するという事実に加えて、構文エラーを犯す試みを無視するという点で興味深いです。 つまり、エラーは発生せず、出力は常に何らかの tsqueryになります。
=# select websearch_to_tsquery('-"foo bar" ((( baz or or qux !@#$%^&*_+-=');
websearch_to_tsquery
--------------------------------------
!( 'foo' <-> 'bar' ) & 'baz' | 'qux'
関数の別の機能は、括弧を無視するという事実に注意する必要があります。 つまり、次のようなものではありません。
=# select websearch_to_tsquery('foo and (bar or baz)');
websearch_to_tsquery
-----------------------
'foo' & 'bar' | 'baz'
この動作は、通常の人々(ITの人々ではない:trollface :)が実際にはブラケットを使用しないという理由で選択されました。 それらを無視するだけで、「関数がエラーで終了しないようにする」機能の実装が大幅に簡素化され、クエリの解析が高速になります。 おそらく、括弧のサポートを含むフラグは将来のバージョンで表示されるでしょう。
このようなシンプルだが便利な機能。 少なくとも、PostgreSQLでの全文検索が以前ほど悪化することはなく、開発者はアプリケーションのコードを簡素化できます。