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

pgroonga_match_positions_byte関数

1.0.7で追加。

概要

pgroonga_match_positions_byte関数は指定したテキスト中にある指定したキーワードの位置を返します。単位はバイトです。HTML出力用にキーワードをハイライトしたいならpgroonga_snippet_html関数またはpgroonga_highlight_html関数の方が適しているでしょう。pgroonga_match_positions_byte関数は高度な用途向けです。

文字単位バージョンが欲しい場合は代わりにpgroonga_match_positions_characterを参照してください。

構文

使い方は2つあります。

integer[2][] pgroonga_match_positions_byte(target, ARRAY[keyword1, keyword2, ...])
integer[2][] pgroonga_match_positions_byte(target, ARRAY[keyword1, keyword2, ...], index_name)

1つ目の使い方は他の使い方よりもシンプルです。多くの場合は1つ目の使い方で十分です。

2つ目の使い方はノーマライザーを変更しているときに便利です。

2つ目の使い方は2.2.8以降で使えます。

以下は1つ目の使い方の説明です。

integer[2][] pgroonga_match_positions_byte(target, ARRAY[keyword1, keyword2, ...])

targetはキーワード検索対象のテキストです。型はtextです。

keyword1keyword2...は見つけたいキーワードです。型はtextの配列です。1つ以上のキーワードを指定しなければいけません。

pgroonga_match_positions_byteは位置の配列を返します。

位置は「オフセット」と「長さ」で表現します。「オフセット」は先頭からキーワードが現れた位置までのバイト数です。「長さ」はマッチしたテキストのバイト数です。「長さ」はキーワードの長さと違うかもしれません。これはキーワードもマッチしたテキストも正規化されるからです。

以下は2つ目の使い方の説明です。

integer[2][] pgroonga_match_positions_byte(target, ARRAY[keyword1, keyword2, ...], index_name)

targetはキーワード検索対象のテキストです。型はtextです。

keyword1keyword2...は見つけたいキーワードです。型はtextの配列です。1つ以上のキーワードを指定しなければいけません。

index_nameは対応するPGroongaのインデックス名です。text型です。

index_nameにはNULLを指定できます。

NormalizerNFKC100のようにNormalizerAuto以外のノーマライザーを使っている場合は、index_nameを使うとよいです。この関数はデフォルトでNormalizerAutoノーマライザーを使います。これにより意図しない結果になることがあります。

例です。

CREATE TABLE memos (
  content text
);

CREATE INDEX pgroonga_content_index
          ON memos
       USING pgroonga (content)
        WITH (normalizer='NormalizerNFKC121');

これでindex_namepgroonga_content_indexを指定できます。

SELECT pgroonga_match_positions_byte('Reiwa: ㋿',
                                     ARRAY['令和'],
                                     'pgroonga_content_index');
--  pgroonga_match_positions_byte 
-- -------------------------------
--  {{7,3}}

pgroonga_match_positions_byteは位置の配列を返します。

位置は「オフセット」と「長さ」で表現します。「オフセット」は先頭からキーワードが現れた位置までのバイト数です。「長さ」はマッチしたテキストのバイト数です。「長さ」はキーワードの長さと違うかもしれません。これはキーワードもマッチしたテキストも正規化されるからです。

これは2.2.8以降で使えます。

使い方

少なくとも1つキーワードを指定しなければいけません。

SELECT pgroonga_match_positions_byte('PGroonga is a PostgreSQL extension.',
                                     ARRAY['PostgreSQL']) AS match_positions_byte;
--  match_positions_byte 
-- ----------------------
--  {{14,10}}
-- (1 row)

複数のキーワードを指定できます。

SELECT pgroonga_match_positions_byte('PGroonga is a PostgreSQL extension.',
                                     ARRAY['Groonga', 'PostgreSQL']) AS match_positions_byte;
--  match_positions_byte 
-- ----------------------
--  {{1,7},{14,10}}
-- (1 row)

pgroonga_query_extract_keywords関数を使うとクエリーからキーワードを抽出できます。

SELECT pgroonga_match_positions_byte('PGroonga is a PostgreSQL extension.',
                                     pgroonga_query_extract_keywords('Groonga PostgreSQL -extension')) AS match_positions_byte;
--  match_positions_byte 
-- ----------------------
--  {{1,7},{14,10}}
-- (1 row)

文字は正規化されます。

SELECT pgroonga_match_positions_byte('PGroonga + pglogical = replicatable!',
                                     ARRAY['Pg']) AS match_positions_byte;
--  match_positions_byte 
-- ----------------------
--  {{0,2},{11,2}}
-- (1 row)

マルチバイト文字にも対応しています。

SELECT pgroonga_match_positions_byte('10㌖先にある100キログラムの米',
                                     ARRAY['キロ']) AS match_positions_byte;
--  match_positions_byte 
-- ----------------------
--  {{2,3},{20,6}}
-- (1 row)

PGroongaのインデックス名を指定するとノーマライザーをカスタマイズできます。

CREATE TABLE memos (
  content text
);

CREATE INDEX pgroonga_content_index
          ON memos
       USING pgroonga (content)
        WITH (normalizer='NormalizerNFKC121');

SELECT pgroonga_match_positions_byte('Reiwa: ㋿',
                                     ARRAY['令和'],
                                     'pgroonga_content_index');
--  pgroonga_match_positions_byte 
-- -------------------------------
--  {{7,3}}
-- (1 row)

参考