2021年10月29日金曜日

Oracle APEX 21.2新機能(7) - スマート・フィルタ

 Oracle APEX 21.2より新しい検索のためのコンポーネントとして、スマート・フィルタが追加されました。ファセット検索と同様の仕組みで検索を行いますが、検索条件を指定するユーザー・インターフェースが異なります。スマート・フィルタでは、ファセットの代わりにフィルタというコンポーネントが使用されます。

Oracle APEXの公式のYouTubeチャンネルよりSmart Filtersの紹介動画が公開されています。10月21日14時(UTC)にAskTOMのOffice HourとしてOracle APEX 21.2 New Featuresというタイトルのオンライン・セミナーがあり、その中で開発者のJohn SnydersよりSmart Filtersの説明がありました。こちらの方は、今のところ動画が公開されていません。

スマート・フィルタについて理解するため、サンプル・データセットEMP/DEPTに含まれる表EMPソースとした、スマート・フィルタのページを作成してみます。ページを作成するアプリケーションは、サンプル・データセットのインストールと同時に作成したもの(デモ - 従業員 / 部門)を使用します。

ページ作成ウィザードを開始します。スマート・フィルタのページはレポートの一種なので、コンポーネントレポートを選択します。


スマート・フィルタを選択します。


ページ名をスマート・フィルタとします。ページ番号7になっています。今後の説明に出てくるフィルタの名前にページ番号が付けられるので、異なる番号になる場合はフィルタ名も変わります。へ進みます。


ナビゲーションのプリファレンスとして新規ナビゲーション・メニュー・エントリの作成を選択します。新規ナビゲーション・メニュー・エントリはデフォルトでページ名と同じスマート・フィルタになります。へ進みます。


レポート・ソースを指定します。表/ビューの名前としてEMPを選択します。表示形式としてレポート(クラシック・レポート)を選択します。ダイアログを広げるか表示をスクロールすると、デフォルトで作成されるフィルタが確認できます。今回の例ではページ作成ウィザードによって、列JOBMGRSALDEPTNOを対象とした4つのフィルタが作成されます。作成をクリックします。


スマート・フィルタを含んだ検索ページが作成されます。検索フィールドP7_SEARCHと4つのフィルタ、P7_DEPTNOP7_MGRP7_JOBP7_SALが含まれます。


ページを実行してみます。ページ上部に検索フィールドと4つのフィルタがあることが確認できます。


レポートの表示に適用されたフィルタは検索フィールドに表示されます。検索フィールドの下に表示されているのは、こういう条件で検索すると有効だと思われるという推奨(サジェスチョン・チップ - Suggetion Chips)でありレポートの検索には適用されていません。

 
それぞれのフィルタ条件はANDで連結されます。レポートの検索に使用されるSELECT文のイメージは以下になります(実際にはもっと複雑です)。それぞれのフィルタ条件が確定した時に、レポートのリフレッシュが実行されます。フィルタもリフレッシュされ、サジェスチョン・チップが変わります。

SELECT * FROM EMP
WHERE
    Departmentのフィルタ条件
AND
    Managerのフィルタ条件
AND
   Jobのフィルタ条件
AND
   Salaryのフィルタ条件

スマート・フィルタを実装するために、リージョン・タイプとしてスマート・フィルタが新設されています。


スマート・フィルタのリージョンは、フィルタ検索フィールドをひとつだけ含みます。今回の例ではP7_SEARCHです。検索フィールドではソース自体と、設定されたフィルタによって適用できる条件を検索します。特殊なコンポーネントで、カスタマイズの余地はほぼありません。


開発者はフィルタをカスタマイズすることにより、検索ページを使いやすくします。

選択可能なフィルタのタイプは、チェック・ボックス・グループラジオ・グループ入力値範囲の4つです。タイプとして検索がありますが、これは前記の通り特別なので追加することはありません。

フィルタのプロパティは、ほとんどファセット検索のファセットと同じです。サジェスチョンがフィルタ独自の設定になります。


フィルタP7_DEPTNOを調整します。タイプチェック・ボックス・グループ外観アイコンとしてfa-building-oサジェスチョンタイプ動的とし、ラベル表示OFFにします。


ページを実行してフィルタを確認します。サジェスチョンラベルの表示OFFとしたので、ラベルの表示が無くなっています。ラベルの表示が無くてもフィルタの条件が明らかな場合にOFFにします。


Departmentのサジェスチョンはセールスになっています。サジェスチョンタイプ動的であると、フィルタのリスト・エントリの先頭がサジェスチョンとして選択されます。フィルタのリスト・エントリのプロパティ上位件数でソートONであれば、件数の一番多いエントリがリストの先頭になります。結果として、その値がサジェスチョンとして選択されます。
サジェスチョンセールスをクリックすると、Departmentセールスの従業員だけがリストされます。


検索結果が少ない場合、サジェスチョン・チップが表示されなくなります。この条件についての記載は見つかりませんでしたが、操作した感じでは検索結果が10行を切ると表示されなくなるようです。サジェスチョン・チップが表示されないだけで、検索フィールドよりフィルタを設定することはできます。


チェック・ボックス・グループのフィルタで選択したエントリはOR条件になります。つまり、以下の画面の場合、Departmentがセールスまたは研究開発である従業員が検索されます。


設定したアイコンは検索フィールドからフィルタの一覧を表示したときに現れます。


サジェスチョンタイプには動的の他に、なし静的SQL問合せがあります。サジェスチョンタイプとして静的値を選択し、静的値として10(会計)を指定します。


サジェスチョン・チップの表示がDEPTNO10である会計に変わります。静的値はサジェスチョンを固定する場合に使用できます。SQL問合せでは、状況に応じたサジェスチョンを指定することができます。


サジェスチョンのタイプのヘルプには、サジェスチョンの値としてカンマ区切りのリストを受け付けるとの記載がありますが、常にリストの先頭の値が有効に見受けられます。複数の値を指定した場合にどのようなサジェスチョンになるかも不明なので、静的値として指定する値はひとつにした方が良いでしょう。

続いてフィルタP7_MGRを調整します。識別タイプラジオ・グループに変更します。ラジオ・グループで選択できるエントリはひとつだけになります。外観アイコンfa-userとし、リスト・エントリゼロ件のエントリ非表示上位件数でソートONにします。


フィルタP7_MGRの表示は以下のようになり、誰の上司でもない従業員はリストされず、また、選択できる従業員はひとりだけになっています。


フィルタP7_SAL識別タイプ範囲になっています。フィルタは以下のように表示されます。


LOVタイプとして静的値が選択され、静的値には複数の範囲が設定されています。


範囲の設定です。


COMMを対象としたフィルタを作成します。フィルタの作成を実行します。識別名前P7_COMMタイプには入力フィールドを選択します。ラベルCommとします。

設定比較演算子Less Than or Equalsを選択し、現行ラベルコミッションは%0以下接頭辞テキスト$接尾辞テキストドルとします。一般的にはこういった冗長な設定はしませんが、これらの文字が画面上のどこに表示されるか確認するために使います。外観アイコンfa-dollarソースデータベース列としてCOMMデータ型NUMBERを選択します。列COMMに定義された型を参照せずVARCHAR2がデフォルトとなるようなので、必ずNUMBER型に変更します。


以上の設定でフィルタP7_COMMを呼び出すと以下になります。入力フィールドの前に接頭辞テキスト、後ろに接尾辞テキストが表示されています。入力フィールド100を入力します。


現行テキストに含まれる%0が入力値に置き換わり、コミッションが100以下と表示されます。


フィルタはファセットと同様に複数の値(マルチ・バリュー)をサポートします。以前の記事で紹介したスキルを検索対象に追加して、複数の値に対応したフィルタを作成します。レポート・リージョン検索結果ソースタイプSQL問合せに変更し、SQL問合せとして以下を記述します。
select 
    e.EMPNO,
    e.ENAME,
    e.JOB JOB,
    e.MGR,
    e.HIREDATE,
    e.SAL,
    e.COMM,
    e.DEPTNO,
    s.SKILLS
from EMP e left outer join 
(
    select empno, 
        json_arrayagg(skill order by id returning varchar2(400)) skills
    from skills group by empno
) s
on e.empno = s.empno
理由は不明ですが、列e.JOBに別名としてJOBを付けないと検索が正常に行われませんでした。そのためe.JOB JOBとしています。


追加された列SKILLSを対象としたフィルタを作成します。

識別名前P7_SKILLSタイプチェック・ボックス・グループを選択します。ラベルSkillsとします。LOVタイプ個別値です。


サジェスチョンデフォルトタイプ動的ラベルを表示ONになっています。ソースデータベース列SKILLSデータ型VARCHAR2です。複数の値タイプJSON配列を選択し、フィルタの結合AND(論理積)を指定します。


フィルタの結合としてAND(論理積)を選んでいるため、日本語英語を選択したときにSkillsに両方が含まれている列だけがレポートに表示されます。


最後にサジェスチョン・チップが表示される数を調整します。スマート・フィルタのリージョンのAttributesを開きます。設定最大サジェスチョン・チップその他のフィルタ・サジェスチョン・チップONに変更します。最大サジェスチョン・チップが未指定の場合は、5として扱われます。


サジェスチョン・チップは以下のように表示されます。


この他にもキーボードによる操作ができるといった機能もあります。

以上でスマート・フィルタの紹介は終了です。

今回実装した内容のエスクポートを以下に置きました。ページ番号7にスマート・フィルタのページを作成しています。
https://github.com/ujnak/apexapps/blob/master/exports/new212-smartfilters.sql

Oracle APEXのアプリケーション作成の参考になれば幸いです。

追記

スマート・フィルタを開発したJohn Snydersさんによる解説が、Oracle APEXのOffice HourのOracle APEX 21.2 New Featuresとして公開されています。元々、今回の記事はリアルタイムでこのセッションを見て書いているのですが、録画を視聴して気づいた機能を2つ追記します。

ページ作成ウィザードでスマート・フィルタのページを作る際にブレッドクラムをつけると、スマート・フィルタはブレッドクラムの位置に作成されます。

ページ作成ウィザードでのブレッドクラムの選択は以下になります。


作成されたスマート・フィルタのページは以下の構成になります。検索親リージョンブレッドクラムになっています。


作成されたページは以下になり、スマート・フィルタがブレッドクラムに配置されます。


スマート・フィルタは検索のUIとして領域が小さいというのが利点ですが、検索フィールドのプロパティ縮小された検索フィールドONにすると、初期状態で検索フィールドを非表示にすることができます。


検索フィールドを開くには虫メガネのアイコンをクリックします。クリックすると検索フィールドが現れ、2つまえの画面ショットになります。