これはPGroonga 2.X and 3.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。

&~|演算子

2.2.1で追加。

概要

&~|演算子は正規表現の配列を使った正規表現検索をします。もし1つ以上の正規表現がマッチしたらそのレコードはマッチします。

PostgreSQLは次のような組み込みの正規表現演算子を提供しています。

SIMILAR TOはSQL標準をベースにしています。「POSIX正規表現」はPOSIXをベースにしています。これらはそれぞれ違う正規表現の構文を使います。

この演算子はさらに別の正規表現の構文を使います。この演算子はRubyで使われている構文を使います。なぜなら、PGroongaはRubyが使っている正規表現エンジンと同じエンジンを使っているからです。そのエンジンはOnigmoです。完全な構文定義はOnigmoのドキュメントを参照してください。

この演算子はマッチ前に対象文字列を正規化します。これは「POSIX正規表現」の~*演算子と似ています。~*演算子は大文字小文字の違いを無視してマッチしているかを判断します。

正規化と大文字小文字の違いを無視することは違います。通常、正規化のほうがよりパワフルです。

例1:「A」も「a」も「」(U+FF21 FULLWIDTH LATIN CAPITAL LETTER 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_expressions

columnは検索対象のカラムです。型はtext型かvarchar型です。

regular_expressionsはパターンとして使う正規表現の配列です。columntext型の場合はtext[]型です。columnの型がvarcharの場合varchar[]型です。

columnの値がregular_expression内の1つ以上のパターンにマッチしたらその式はtrueになります。

演算子クラス

この演算子を使うには次のどれかの演算子クラスを指定する必要があります。

使い方

以下は例で使うサンプルスキーマです。

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 is a relational database management system');
INSERT INTO memos VALUES (2, 'Groonga is a fast full text search engine that supports all languages');
INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga as index');
INSERT INTO memos VALUES (4, '*.pgn* files are used by PGroonga');

&~|演算子で正規表現の配列を使って正規表現検索をできます。

SELECT * FROM memos WHERE content &~| ARRAY['\Apostgresql', 'pgroonga\z'];
--  id |                        content                        
-- ----+-------------------------------------------------------
--   1 | PostgreSQL is a relational database management system
--   4 | *.pgn* files are used by PGroonga
-- (2 rows)

\Apostgresql」の中の「\A」はRubyの正規表現構文では特別な記法です。これはテキストの最初という意味です。つまり、このパターンは「postgresql」がテキストの最初に現れること、という意味です。

pgroonga\z」の中の「\z」はRubyの正規表現構文では特別な記法です。これはテキストの最後という意味です。つまり、このパターンは「pgroonga」がテキストの最後に現れること、という意味です。

どうして「PostgreSQLは...」レコードがマッチしているのでしょうか?この演算子はマッチ前にマッチ対象のテキストを正規化することを思い出してください。つまり、「PostgreSQLは...」テキストはマッチ前に「postgresqlは...」と正規化されるということです。正規化されたテキストは「postgresql」で始まっています。そのため、「\Apostgresql」正規表現はこのレコードにマッチします。

PGroongaはPostgreSQLの...」レコードはマッチしません。このレコードは正規化後のテキストに「postgresql」を含んでいますが、「postgresql」はテキストの先頭には現れていません。そのためマッチしません。

どうして「... used by PGroonga」レコードがマッチしているのでしょうか?この演算子はマッチ前にマッチ対象のテキストを正規化することを思い出してください。つまり、「... used by PGroonga」テキストはマッチ前に「... used by pgroonga」と正規化されるということです。正規化されたテキストは「pgroonga」で終わっています。そのため、「pgroonga\z」正規表現はこのレコードにマッチします。

PGroonga is a PostgreSQL ...」レコードはマッチしません。このレコードは正規化後のテキストに「pgroonga」を含んでいますが、「pgroonga」はテキストの最後に現れていません。そのためマッチしません。

参考