これはPGroonga 2.X and 3.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。
&~
演算子1.2.1で追加。
&~
演算子は正規表現検索をします。
PostgreSQLは次のような組み込みの正規表現演算子を提供しています。
SIMILAR TO
はSQL標準をベースにしています。「POSIX正規表現」はPOSIXをベースにしています。これらはそれぞれ違う正規表現の構文を使います。
この演算子はさらに別の正規表現の構文を使います。この演算子はRubyで使われている構文を使います。なぜなら、PGroongaはRubyが使っている正規表現エンジンと同じエンジンを使っているからです。そのエンジンはOnigmoです。完全な構文定義はOnigmoのドキュメントを参照してください。
この演算子はマッチ前に対象文字列を正規化します。これは「POSIX正規表現」の~*
演算子と似ています。~*
演算子は大文字小文字の違いを無視してマッチしているかを判断します。
正規化と大文字小文字の違いを無視することは違います。通常、正規化のほうがよりパワフルです。
例1:「A
」も「a
」も「A
」(U+FF21 FULLWIDTH LATIN CAPITAL LETTER A)も「a
」(U+FF41 FULLWIDTH LATIN SMALL LETTER A)もすべて「a
」に正規化されます。
例2:いわゆる全角カタカナも半角カタカナもどちらも全角カタカナに正規化されます。たとえば、「ア
」(U+30A2 KATAKANA LETTER A)も「ア
」(U+FF71 HALFWIDTH KATAKANA LETTER A)もどちらも「ア
」(U+30A2 KATAKANA LETTER A)に正規化されます。
この演算子は正規表現パターンは正規化しないことに注意してください。マッチ対象のテキストだけを正規化します。これは正規表現パターンのなかでは正規化された文字だけを使うべきだということです。
たとえば、パターンに「Groonga
」を使ってはいけません。そうではなく、「groonga
」を使うべきです。なぜなら、対象テキスト中の「G
」は「g
」に正規化されるからです。対象テキスト中に「Groonga
」という文字列は決して現れません。
いくつかのシンプルな正規表現のパターンはGroonga内でインデックスを使って検索します。インデックスを使った場合は非常に高速です。インデックスを使って検索可能なパターンの詳細はGroongaの正規表現のドキュメントを参照してください。
もし、正規表現のパターンをインデックスを使って検索できない場合、Groonga内でシーケンシャルスキャンで検索します。
EXPLAIN
でPostgreSQLがPGroongaのインデックスを使っているとレポートするときでも、Groongaは正規表現のパターンを使った検索をシーケンシャルスキャンで実現するかもしれないことに注意してください。
column &~ regular_expression
column &~ pgroonga_condition(query,
weights,
scorers,
schema_name,
index_name,
column_name,
fuzzy_max_distance_ratio)
1つ目の使い方は他の使い方よりもシンプルです。多くの場合は1つ目の使い方で十分です。
column
は検索対象のカラムです。型はtext
型かvarchar
型です。
regular_expression
はパターンとして使う正規表現です。column
の型がtext
型のときはtext
型です。column
の型がvarchar
型のときはvarchar
型です。
column
の値がregular_expression
パターンにマッチしたら、その式はtrue
を返します。
2つ目の使い方はpgroonga_condition
関数を使います。正規表現だけでなく、スコアーやシーケンシャルサーチで使われるインデックス情報も指定できます。
2つ目の使い方は3.2.5から使えます。
pgroonga_condition
functionのquery
はパターンとして使う正規表現です。text
型です。
詳細はpgroonga_condition
関数を参照してください。
正規表現検索ではfuzzy_max_distance_ratio
は使われないことに注意してください。
この演算子を使うには次のどれかの演算子クラスを指定する必要があります。
pgroonga_text_regexp_ops_v2
:text
用
pgroonga_text_array_regexp_ops_v2
:text[]
用
pgroonga_varchar_regexp_ops_v2
:varchar
用
pgroonga_text_regexp_ops
:text
用
pgroonga_varchar_regexp_ops
:varchar
用
以下は例で使うサンプルスキーマです。
CREATE TABLE memos (
id integer,
content text
);
CREATE INDEX pgroonga_content_index ON memos
USING pgroonga (content pgroonga_text_regexp_ops_v2);
以下は例で使うデータです。
INSERT INTO memos VALUES (1, 'PostgreSQLはリレーショナル・データベース管理システムです。');
INSERT INTO memos VALUES (2, 'Groongaは日本語対応の高速な全文検索エンジンです。');
INSERT INTO memos VALUES (3, 'PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。');
INSERT INTO memos VALUES (4, 'groongaコマンドがあります。');
&~
演算子を使うと正規表現検索を実行できます。
SELECT * FROM memos WHERE content &~ '\Apostgresql';
-- id | content
-- ----+------------------------------------------------------------
-- 1 | PostgreSQLはリレーショナル・データベース管理システムです。
-- (1 row)
「\Apostgresql
」の中の「\A
」はRubyの正規表現構文では特別な記法です。これはテキストの最初という意味です。つまり、このパターンは「postgresql
」がテキストの最初に現れること、という意味です。
どうして「PostgreSQLは...
」レコードがマッチしているのでしょうか?この演算子はマッチ前にマッチ対象のテキストを正規化することを思い出してください。つまり、「PostgreSQLは...
」テキストはマッチ前に「postgresqlは...
」と正規化されるということです。正規化されたテキストは「postgresql
」で始まっています。そのため、「\Apostgresql
」正規表現はこのレコードにマッチします。
「PGroongaはPostgreSQLの...
」レコードはマッチしません。このレコードは正規化後のテキストに「postgresql
」を含んでいますが、「postgresql
」はテキストの先頭には現れていません。そのためマッチしません。