GF70  JSPチェック結果テーブル
	ファイル名		FILENAME	X(60)
	ファイルパス	FILEPATH	X(256)

ファイルパス には、ファイル名を含むフルパスになっています。
FILE_DATASTORE を使ってみます。

①使用できるように、FILE_ACCESS_ROLE を付与します。
  ここでは、public にしてしまいます。

（実行はSYSユーザで行う）
	connect sys/system -sysdba

EXECUTE CTXSYS.CTX_ADM.SET_PARAMETER('FILE_ACCESS_ROLE','public');

******* 本当は、ROLE を設定して、そのROLEをユーザーに与える。 *******
BEGIN
	CTXSYS.CTX_ADM.SET_PARAMETER('FILE_ACCESS_ROLE','TOPCAT');
END;
*********************************************************************

②-1.FILE_DATASTORE のプリファレンスを作成します。
  これは、サンプル的に、FILEPATH に、jspファイルのｱﾄﾞﾚｽを用意して、それにｲﾝﾃﾞｯｸｽを作成します。
  FILE_DATASTORE で、PATH属性を指定すると、索引付けは単純なファイル名のみになり、パスと結合することはできません。
  ファイルが複数のフォルダまたはディレクトリに存在する場合、PATH属性を設定せずに、
  索引付けされた列にPATHを含む完全なファイル名を指定する必要があります。

BEGIN
	CTX_DDL.CREATE_PREFERENCE('F_DS','FILE_DATASTORE');
--	CTX_DDL.SET_ATTRIBUTE('F_DS','PATH','/mydocs');
END;

②-2.インデックスの作成。
  CTXSYS.CONTEXT で、先ほどの、DATASTORE を指定します。
CREATE INDEX GF70_PATH_IDX ON GF70(FILEPATH)
	INDEXTYPE IS CTXSYS.CONTEXT
	PARAMETERS ('DATASTORE F_DS');

③.フィルターの解除
  jspは、XMLなので、フィルタ処理を行わない様に、NULL_FILTER を使用します。
  プレーン・テキスト、HTMLまたはXMLドキュメントの索引付けに使用します。
  WORDやEXCELを解析する場合は、デフォルトの AUTO_FILTER で構いません。(つまり指定する必要がない)

DROP INDEX GF70_PATH_IDX;

CREATE INDEX GF70_PATH_IDX ON GF70(FILEPATH)
	INDEXTYPE IS CTXSYS.CONTEXT
	PARAMETERS ('DATASTORE F_DS FILTER CTXSYS.NULL_FILTER');

④.日本語用のﾚｸｻｰも追加します。
  JAPANESE_LEXER と JAPANESE_VGRAM_LEXER がありますが、JAPANESE_LEXER を使用します。
  これは、文をワードに変換するために、内部ディクショナリが参照されます。
  トークンを固定文字数ごとに切り出す JAPANESE_VGRAM_LEXER と比較して、
  小型の索引の生成、問合せ応答時間の短縮、実ワード・トークンの生成による問合せ精度の向上 という
  利点がありますが、索引付けに要する時間は、JAPANESE_VGRAM_LEXERを使用した場合より長くなります。

BEGIN
	CTX_DDL.CREATE_PREFERENCE('JPN_LX','JAPANESE_LEXER');
END;

DROP INDEX GF70_PATH_IDX;

CREATE INDEX GF70_PATH_IDX ON GF70(FILEPATH)
	INDEXTYPE IS CTXSYS.CONTEXT
	PARAMETERS ('DATASTORE F_DS FILTER CTXSYS.NULL_FILTER LEXER JPN_LX');


⑤全文検索用のトークンが参照できる。GF70_PATH_IDX はさっき作ったインデックスを指定します。
select count(*) from DR$GF70_PATH_IDX$I ;
SELECT TOKEN_TEXT FROM DR$GF70_PATH_IDX$I ORDER BY TOKEN_TEXT;


⑥検索してみます。
SELECT * FROM GF70 WHERE CONTAINS (FILEPATH, 'upload') > 0;


SELECT * FROM GF70 WHERE CONTAINS (FILEPATH, 'LEE & UTSUNOMIYA & MURAKAMI & 費目') > 0;


SELECT * FROM GF70 WHERE CONTAINS (FILEPATH, '訂正記事') > 0;

=====================================================
テキスト索引の同期化
EXEC CTX_DDL.SYNC_INDEX( 'GF70_PATH_IDX' );

テキスト索引のメンテナンス
EXEC CTX_DDL.OPTIMIZE_INDEX( 'GF70_PATH_IDX','FAST' );

削除されて既に検索対象表に存在していないトークンを削除
EXEC CTX_DDL.OPTIMIZE_INDEX( 'GF70_PATH_IDX','FULL' );

=====================================================
⑦SNIPPET
  ドキュメントの用語索引を作成するには、CTX_DOC.SNIPPETプロシージャを使用します。
  用語索引とは、問合せ語句とその前後のテキストを含むテキストの断片（フラグメント）です。
  この用語索引は、マークアップされた問合せキーワードを前後のテキストと一緒に戻すため、
  文脈付きキーワード（KWIC）としても知られており、ユーザーは問合せキーワードを文脈で評価できます。

※通常は、問合せの後で処理するドキュメントを特定してから使用する

SELECT UNIQ FROM GF70 WHERE CONTAINS (FILEPATH, '訂正記事') > 0;
結果、UNIQ = 190726 の SNIPPET を求める。
select CTX_DOC.SNIPPET('GF70_PATH_IDX','190726','訂正記事') from dual

実際には、プライマリキーを JOIN することで、検索結果の 用語索引
を取り出すことができますが、何か別の方法を考えるべき？

select CTX_DOC.SNIPPET('GF70_PATH_IDX',UNIQ,'訂正記事')
	from GF70
	WHERE CONTAINS (FILEPATH, '訂正記事') > 0;


スコアを戻すには、SCORE演算子を指定します。
逆順に表示すれば、スコアの高い順に表示できます。

select SCORE(1),CTX_DOC.SNIPPET('GF70_PATH_IDX',UNIQ,'訂正記事')
	from GF70
	WHERE CONTAINS (FILEPATH, '訂正記事',1) > 0
	ORDER BY SCORE(1) DESC ;


表示件数を絞るには、副問合せで、ROWNUM を使います。
件数を絞り込んでから、SNIPPET を表示させます。

select SCR,CTX_DOC.SNIPPET('GF70_PATH_IDX',UNIQ,'訂正記事') as TXT
from (
	select SCORE(1) as SCR,UNIQ
		from GF70
		WHERE CONTAINS (FILEPATH, '訂正記事',1) > 0
		ORDER BY SCORE(1) DESC
)
where rownum < 11

