Oracle APEX 22.1よりアプリケーション定義のプロパティに、行検索のトークン化が追加されています。
コンポーネントで行検索が行われた場合に、検索語がどのように適用されるかを指定します。
「オン」を選択すると、検索語のそれぞれの単語が別々に処理されます。全体であれ個別であれ、列に検索語が含まれていればレコードが一致します。フレーズ全体を検索するには、検索語を二重引用符(")で囲み、"ui developer"のようにします。検索語の中の二重引用符をエスケープするには、二重引用符("")を使用します。
例1- redおよびshoesという語を含む任意のレコード検索: red shoes2- developerという語とui designerという表現全体を含む任意のレコード検索: developer "ui designer"3- authorという語と、the sky is "blue" and niceという表現全体を含む任意のレコード検索語: author "the sky is ""blue"" and nice"
「オフ」を選択すると、検索語全体が完全一致として扱われます。
Oracle APEX 22.1で新規に作成したアプリケーションでは、デフォルトでONになっています。
こちらの記事で作成した簡易ファイル管理アプリケーションを使って、行検索のトークン化の効果を確認します。
今回の動作確認では、対話モード・レポートを使用します。これ以外にスマート・フィルタ、ファセット検索、対話グリッド、ポップアップLOVなど、行検索がサポートされているすべてのコンポーネントで機能します。
テストに使用するデータとして、Oracle APEX情報サイトよりPDFで提供されているファイルをいくつかアップロードしています。
Oracle Textによる全文検索との関係
レポートにOracle Text索引列が設定されている場合は、Oracle Textによる検索が優先されます。この場合、行検索のトークン化の設定は意味を持ちません。
対話モード・レポートでは、属性の詳細のOracle Text索引列に、Oracle Text索引が作成されている列を指定します。今回のサンプル・アプリケーションでは、表SIMPLE_CONTENTSの列TITLEを指定します。
Oracle and Daysを検索語として行検索を行います。OracleとDaysを含む文書が3件検索されました。
デバッグ・ログより実際に実行されているSELECT文を確認してみます。
もっとも内側で実行されているSELECT文の、WHERE句として与えられている条件は以下になります。
contains("TITLE",:apex$f1,1)>0
バインド変数の:apex$f1に、検索語のOracle and Daysが渡されています。
行検索のトークン化がOFFの場合
Oracle Daysを検索語として行検索を行います。結果は0件になります。行検索のトークン化がOFFの場合、検索語Oracle Daysと完全一致する単語を含む行のみが検索結果となります。
(
instr( upper("TITLE"),upper(:apex$f1)) > 0
or
instr( upper("ABSTRACT"),upper(:apex$f1)) > 0
)
バインド変数の:apex$f1に、検索語のOracle Daysが渡されています。
バインド変数の:apex$f1に、検索語のOracle Daysが渡されています。
この条件であれば、検索結果は0件になります。
行検索のトークン化がONの場合
APEX 22.1で追加されたプロパティ行検索のトークン化をONにしたときの結果です。OFFの場合と同様に検索語としてOracle Daysを与えて行検索を行います。
行検索のトークン化がONの場合、検索結果が3件になりました。
デバッグ・ログよりWHERE句の条件を確認します。
(
instr( upper("TITLE"),upper(:apex$f1)) > 0
or
instr( upper("ABSTRACT"),upper(:apex$f1)) > 0
)
and
(
instr( upper("TITLE"),upper(:apex$f2)) > 0
or
instr( upper("ABSTRACT"),upper(:apex$f2)) > 0
)
行検索に与えられた検索語Oracle Daysは空白で区切られ、Oracleは:apex$f1、Daysは:apex$f2に割り当てられます。結果としてOracleとDaysが含まれている表示列があれば、検索結果に含まれます。
行検索に与えられた検索語Oracle Daysは空白で区切られ、Oracleは:apex$f1、Daysは:apex$f2に割り当てられます。結果としてOracleとDaysが含まれている表示列があれば、検索結果に含まれます。
今回は列ABSTRACTにOracleとDaysの両方が含まれているデータが3件ありました。
Oracle Text関数
本題から外れますが、近いトピックなのでOracle Text関数も使ってみます。
ファンクションconvert_end_user_searchを作成します。
create or replace function convert_end_user_search (
p_search in varchar2 )
return varchar2
is
begin
return 'FUZZY({' || replace( p_search, '}', '\}' ) || '}, 30, 2000)';
end;
これはOracle Text関数のオンライン・ヘルプに記載のある、Oracle Text CONTAINS問合わせ演算子のFUZZY関数を使った例です。
アプリケーション定義のプロパティのOracle Text関数として、convert_end_user_searchを設定します。
検索語としてOlacle Daysを与えて、行検索を行ってみます。Oracleではなくスペルが間違っているOlacleです。
FUZZY検索が行われるため、スペルが間違っていても、検索結果として3件返されます。
これも条件句を確認してみます。
convert_end_user_searchが返す文字列は、:apex$f1がOlacle Daysであれば以下になります。
FUZZY({Olacle Days}, 30, 2000)
FUZZY({Olacle Days}, 30, 2000)
結果として、上記の条件句は以下になります。
contains("TITLE",'FUZZY({Olacle Days}, 30, 2000)',1)>0
Oracle APEX 22.1で追加された、行検索のトークン化についての説明は以上になります。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完