[an error occurred while processing this directive] [an error occurred while processing this directive]


プログラミング
逆引き
クライアントとの通信
VisMでの通信
Factoryでの通信
WebServiceでの通信
CSP (Cache' Server Pages)
Cache'SQL
設定・性能


【広告】









全文検索

Full text search..

 文章に含まれる文字列で検索したい場合、Grepとかspotlight検索とか使ったりしますよね。(windowsのは何て呼ぶんでしょうね)

 Cache'で「含まれる文字列の検索」を行う場合は、グローバルを$Orderや$Queryでアクセスして、包含 [ 演算で該当したものを見つけたりします。でも、この方法では検索の度に全データにアクセスするので、データ量が増えてくると遅くなってしまいます。これはGrepと同じです。

 そこで、あらかじめインデックスグローバルを作っておき、検索時にはインデックスグローバルにアクセスするだけで該当するデータを見つけることができるようにしていました。

 最近のCache'では全文検索機能が搭載されたので、面倒なく簡単に「含まれる文字列の検索」ができるようになりました。

 今回は、この全文検索を試してみます。


%Text.Textクラスを使ってクラスを作る

全文検索は%Text.Textクラスで提供されています。日本語で使用する場合は、%Text.Textを継承した%Text.Japaneseクラスを使用します。
マニュアル上の全文検索の説明としては、%Text.Textクラスの説明が一番詳しいのではないかと思います。

例として、製品マスタ・クラス Test.Product を作成します。この中のDescriptionプロパティに対して全文検索を行えるようにします。
/// 全文検索のテスト
Class Test.Product Extends %Persistent
{
/// 商品コード
Property Code As %String(MAXLEN = 10) [ Required ];
Index CodeIndex On Code [ Unique ];

/// 製品名
Property Name As %String [ Required ];

/// 製品説明
Property Description As %Text (MAXLEN = 36000, LANGUAGECLASS = "%Text.Japanese");
Index DescriptionIndex On "Description(KEYS)" [ Type = bitmap ];
}
最後の2行(太字の部分)がキモです。簡単に説明します。
Descriptionプロパティは%Text型で文字列長は3.6万文字、解釈を行うクラスとして%Text.Japaneseを指定しました。
また、このインデックスとしてDescriptionIndexを作成し、%Text.Japaneseクラスが解釈した結果であるKEYについてインデックスを作成します。
今回はビットマップ型インデックスとしました。

データを投入する

作成したTest.Productクラスにデータを登録します。
ターミナルから以下のように入力します。
USER> Set x=##class(Test.Product).%New()

USER> Set x.Code="ISW11K"

USER> Set x.Name="DIGNO"

USER> Set x.Description="WiMAX搭載スーパースリム、防水対応スマートフォン。スリムボディーに、「充実機能」と「使いやすさ」を凝縮。WiMAX搭載で高速モバイル通信を実現し、インターネット接続を快適にします。単体での利用はもちろん、本体をWi-Fiルーターとして利用することも可能です。"

USER> Do x.%Save()

オブジェクトですので、SQL文でも登録できます。
ターミナルでSQL Shellを使って、Insert文で登録します。
USER>Do $SYSTEM.SQL.Shell()
SQL Command Line Shell
----------------------------------------------------

The command prefix is currently set to: <<nothing>>.
Enter q to quit, ? for help.

USER>>Insert into Test.Product (Code, Name, Description) values ('ISW13F','ARROWS Z','脅威の激速Quad Core CPU搭載。All in oneハイスペック防水スマートフォン。スマートフォンの頭脳でもあるコアCPUを4つ搭載しながら、省電力化も実現。圧巻のグラフィック性能や13.1Mカメラ、HD動画の視聴も快適に楽しめます。指紋認証やプライバシーモードなどのセキュリティ機能、便利な本格辞書も搭載。')

1 Row Affected
statement prepare time: 0.0473s, elapsed execute time: 0.0061s.
---------------------------------------------------------------------------
黒のままだとわかりにくいので、入力した文字はにしてみました。

全文検索、実行

データを登録したので、早速検索を実行してみます。
全文検索は %CONTAINS() 関数を使用します。

引き続きターミナルのSQL ShellでSQL文を入力します。
USER>> SELECT * from Test.Product where Description %Contains('モバイル')3. SELECT * from Test.Product where Description %Contains('モバイル')

ID Code Description Name
1 ISW11K WiMAX搭載スーパースリム、防水対応スマートフォン。スリムボディーに、「充実機能」と「使いやすさ」を凝縮。WiMAX搭載で高速モバイル通信を実現し、インターネット接続を快適にします。単体での利用はもちろん、本体をWi-Fiルーターとして利用することも可能です。 DIGNO

1 Rows(s) Affected
statement prepare time: 0.0012s, elapsed execute time: 0.0012s.
---------------------------------------------------------------------------


USER>> SELECT * from Test.Product where Description %Contains('スマートフォン')

ID Code Description Name
1 ISW11K WiMAX搭載スーパースリム、防水対応スマートフォン。スリムボディーに、「充実機能」と「使いやすさ」を凝縮。WiMAX搭載で高速モバイル通信を実現し、インターネット接続を快適にします。単体での利用はもちろん、本体をWi-Fiルーターとして利用することも可能です。 DIGNO
2 ISW13F 脅威の激速Quad Core CPU搭載。All in oneハイスペック防水スマートフォン。スマートフォンの頭脳でもあるコアCPUを4つ搭載しながら、省電力化も実現。圧巻のグラフィック性能や13.1Mカメラ、HD動画の視聴も快適に楽しめます。指紋認証やプライバシーモードなどのセキュリティ機能、便利な本格辞書も搭載。 ARROWS Z

2 Rows(s) Affected
statement prepare time: 0.0597s, elapsed execute time: 0.0050s.
---------------------------------------------------------------------------
(着色は筆者による)
このように、全文検索が動作することが確認できました。

動作の推定

しかし、この動きでは like '%文字列%' 演算とどう違うのかわかりません。
というか、動きとしては同一の結果が得られます。

違いはデータ量が増えた時に初めて出てきます。
%CONTAINSによる検索は、インデックスを使って検索するため、速度の劣化が少ないのです。

そのインデックスとはどのようなものか見てみましょう。

システム管理ポータルで、対象ネームスペースのグローバルを確認すると次のようになっています。


Test.ProductD 行の表示を押して内容を見てみます

登録したデータが格納されていることが分かります。

前の画面に戻って、Test.ProductI 行の表示を押して内容を見てみます

こちらが、インデックスのようです。

^Test.ProductI("CodeIndex")以下がCodeプロパティに対するインデックス、^Test.ProductI("DescriptionIndex")以下がDescriptionプロパティに対するインデックスです。
下図のように^Test.ProductI("DescriptionIndex")以下はDescriptionの内容が2文字ずつ格納されていることが分かります。


このことから「モバイル」で検索すると、モバイルを2文字ずつに分解し、「モバ」 and 「バイ」 and 「イル」 の検索を行なっていると推定されます。
検索する文字が長くなると、全文検索には多くのand演算が必要になります。
bitmapインデックスはand/or演算が高速に行えるため、全文検索のインデックスにbitmapインデックスを使用することが勧められているのだと思われます。


[an error occurred while processing this directive] [an error occurred while processing this directive]
2012/11/19Update