インデックス作成
注: データーベースからインデックスを作成する場合はこの項で解説している操作は不要です
MindSearchでインデックスを作成する際のパス指定は以下のようになります。(元パスと先パスを指定します)
- インデックス作成元ファイル(原典ファイル)が存在する場所を「検索パス設定」する
- インデックス作成先を指定してインデックスを作成する
1番の原典ファイルのパス指定はさらに「検索ベースパス」と「検索パス」の二つに分けられます。
これに加え、MindSearchシステム自体のベースパスも含めると、インデックス作成に関わるパスとして以下の三つが使われることになります。(インストールディレクトリを /home/foo/mshyper と仮定)。
ペースパス(固定):
/home/foo/mshyper ←インストールディレクトリから自動決定
検索ベースパス設定:
指定例=sample 結果=/home/foo/mshyper/sample
検索パス設定:
指定例=texts/eiga 結果=/home/foo/mshyper/sample/texts/eiga
(例)
CMD:"sample/texts"を検索ベースパス設定 ←相対指定なので上位にMindSearchベースパスが補充される
CMD:"eiga"と"tokkyo"を検索パス設定
CMD:"sample/indexes/twoindexes/mainA"にインデックス作成
まず「検索ベースパス設定」コマンドを使い検索ベースパスを指定します。相対パスを指定した場合はMindSearchのベースパスが上位に補充されて使われます。次に「検索パス設定」コマンドにより検索ベースパスからの相対パスによって検索したいパスを指定するようになっています。
検索ベースパスとは文字通りいくつかの検索パスのベース部分を指定するものです。複数のディレクトリにまたがる原典ファイルを対象とする場合、それらのディレクトリがまったく関係のない(/ 直後から異なるような)ディレクトリであることはまれで、上位ディレクトリは共通であることが多いものです。そのような場合、その上位ディレクトリをまず指定しておき、それ以後のパス変更はそこからの相対パスで指定するのがMindSearchの検索パスの指定方法になります。
パスやファイル名の表記方法
たとえば、PerlでMindSearchのスクリプトを送信することを考えてみます。言語の中に別の言語が入り込むような感じになるため、文字列定数のクオーティングに注意が必要になります。たとえば普通であれば次のような記述になるでしょう。
&msch_sendScript( "CMD:\"sample\"を検索ベースパス設定" );
上記で正しいのですが、PerlとしてのクオーティングとMindSearchスクリプトのクオーティングが衝突するため、エスケープする必要があり、ソースコードが読みずらくなり、間違いも生じやすくなります。
このようなことを回避するため、MindSearchではパスやファイル名の表記にダブルクオート以外の多くの記号を許すようにしています。下記はその例です(本製品付属のサンプルプログラムでは [PATH] の表記を好んで使っています)。
&msch_sendScript( "CMD:'sample'を検索ベースパス設定" );
&msch_sendScript( "CMD:[sample]を検索ベースパス設定" );
上記二つはクオーティングが衝突しないので読み易いコードとなっています。
具体的には以下の記号が使えます。
'PATH'
"PATH"
(PATH)
<PATH>
[PATH]
{PATH}
以下の文法解説では、"PATH" 形式を使いますが実際には前記したような記号に代替することができます。
検索ベースパス設定
(形式)
CMD:"PATH"を検索ベースパス設定
PATH: 任意のパスで、絶対パスでも相対パスでも良い。
相対パスの場合はMindSearchベースパスと合成して絶対パス化される
CMD:""を検索ベースパス設定 とすると、検索ベースパスはデフォルト
のMindSearchベースパスに戻る
(レスポンス)
OK:PATH
PATH: 設定されたパスのフルパス表現
(レスポンスの例)
OK:/home/foo/mshyper/sample
検索パス設定
(形式1)
CMD:"PATH"を検索パス設定
PATH: 相対パスであること
(「検索ベースパス」が加算されて絶対パスとして処理される)
(形式2)
CMD:"PATH+"を検索パス設定
パス末尾に'+'が付くと指定したパス以下のディレクトリ・ツリーを指定したことになる
(形式3)
CMD:"PATH1"と"PATH2"と..を検索パス設定
上記 PATH の部分は PATH+形式(ツリー指定)でも可
(レスポンス)
OK:#n
n: 認識したディレクトリの総数
(レスポンスの例)
OK:#1
複数の検索パスの指定
「検索ベースパス」は常に1つですが、「検索パス」は複数存在できます。複数指定にはさらに2通りの方法があります。1つはパス末尾に'+'記号を付加することで、指定したパスおよびそれ以下の全ディレクトリ・ツリーを指定するものです。もう1つは具体的に複数のパスを列挙する方法です。両方を併用しても構いません。
ルートに近いパスに'+'を付けた場合には大量のディレクトリ・スキャンが発生し、長時間レスポンスが戻って来ない可能性があるのでご注意ください。たとえば検索ベースパスに "/" を指定し、検索パスに "+" を指定することは意味がないだけでなく危険とも言えます。
検索ベースパスと検索パスとの配分
たとえば、以下の二つのやりかたのどちらを使っても同じ検索をおこなうことができます。
(方法1)
--------------------------------------------------------------
検索ベースパス設定:
指定=sample 結果=/home/foo/mshyper/sample
検索パス設定:
指定=texts/eiga 結果=/home/foo/mshyper/sample/texts/eiga
--------------------------------------------------------------
(方法2)
--------------------------------------------------------------
検索ベースパス設定:
指定=sample/texts 結果=/home/foo/mshyper/sample/texts
検索パス設定:
指定=eiga 結果=/home/foo/mshyper/sample/texts/eiga
--------------------------------------------------------------
最終的に算出される検索パスはどちらも同じですが検索結果のSS:レスポンスに違いが出ます。
(方法1) ↓★
SS:1|XFL|texts/eiga/eiga1.txt|20031216010201||||1|1
(方法2) ↓★
SS:1|XFL|eiga/eiga1.txt|20031216010201||||1|1
SS:レスポンス中に記入されるファイル名は検索ベースパスからの相対であるため、上記のようにベースパスを長くとれば短くなり、ベースパスを短くとれば長くなります。どちらでも関係ないというケースも多いでしょうが、アプリケーションによってはSS:レスポンスを受け取ってファイル名を抽出する場面でコーディングに差が出ることがあります。
この違いが重要になるのはWebコンテンツを検索する場合です。
一般的にWebコンテンツは収集ロボットを走らせ、サイト上と同じツリー構造でミラーとしてコンテンツを取り込むことが多いです。そうしておけば、ヒットしたファイルのパスの上位パスを少し加工し、その頭に「http://」などを付加すれば原典URLを生成できます。
たとえば取得したミラーが、サイト名とまったく同じ www.mycompany.co.jp/ というディレクトリ以下に格納されていたとするなら、この直前までのパスを「検索ベースパス」として指定し、"www.mycompany.co.jp+" を検索パス設定することを勧めます。そうすれば、SS:レスポンス中のファイル名部が www.mycompany.co.jp/DIR/DIR/CONTENT.html の形式で得られることになり、この頭に「http://」を付加するだけで容易に元へのURLを合成することができます。もしより上位のディレクトリが付いてしまっていたら、たとえば「三つ目の'/'までをスキップしてその次から取り出し・・といった文字列加工が必要になってしまいます。
サンプルプログラムである sample/program/perlCGI/ または javaCGI/ 内に入っている簡易検索サイトプログラムは以上のことを考慮したパス配分を実際におこなっています。参考にしてください。
検索ベースパスと検索パスの取得
アプリケーションは現在の検索ベースパスと検索パスを取得できます。
検索ベースパス取得
(形式)
CMD:検索ベースパス取得
(レスポンス例)
OK:/foo/mshyper/sample
検索パス取得
(形式)
CMD:検索パス取得
(レスポンス例)
DT:texts/eiga
GET ←アプリケーションからの送信
DT:texts/tokkyo
GET ←アプリケーションからの送信
OK:
コマンドを送出すると設定されているパスの数だけDT:レスポンスが返されます。「DT:」の次の文字以降が1つのパスです。アプリケーションはDT:を処理し終わるごとに「GET」を送信してください。最後に「OK:」を受信したらコマンド終了です。
インデックス生成先は次のようなディレクトリ構造になっています。
(例)
←------------基幹パス-------------→
/home/foo/mshyper/sample/indexes/try/
+- mainA/
+- subA/
+- mainB/
+- subB/
↑末尾フォルダ
←---------------フルパス---------------→
/home/foo/mshyper/sample/indexes/try/mainA
MindSearchでインデックスパスと言った場合、前者の基幹パスのことを差すことが多いのですが、インデックス作成コマンドを実行する場合にはフルパスを使います。そのほかにもフルパスを指定するコマンドがあります。
フルパスの場合に末尾に付加されるフォルダ名を「末尾フォルダ」と呼ぶことにします。末尾フォルダは「main」「sub」それぞれに末尾1文字「A」「B」「S」が付くので計6種類のフォルダ名が存在することになります。
main --- 主インデックスを示す
sub --- 副インデックスを示す
A --- A系統のインデックスであることを示す
B --- B系統のインデックスであることを示す
S --- A/Bを明示せず、MindSearchに判断させることを示す
[main(主インデックス)]
MindSearch Hyperが持つ差分インデックシングの機構上、主インデックス、副インデックスという区別があります。最初に作成するのが主インデックスであり、フォルダ名は「mainX」の綴りを使います。
差分だけを作成する時の生成を副インデックスと呼びます。検索時には主・副インデックスがワンセットとなって使われます。
[sub(副インデックス)]
差分インデックシングを行なう場合には生成先をsubとして指定します。逆に言えば、生成先のインデックスパスの末尾フォルダが「subX」の形式になっているとMindSearchは差分インデックシングの指示であると判断します。
[A/B系統]
検索サービスを行なっている最中に同じマシンを使ってインデックス作成を行なう場合には検索とインデックス作成でディレクトリを分離する必要がありますが、単純に分けたのでは差分インデックシングが正しく機能しません。そのためMindSearchが積極的に2系統のディレクトリの管理を行なうようになっています。この2つをA系統、B系統と呼びます。A/B系統それぞれに主/副インデックスが存在するため、一つの基幹パスに対して内部的には4種のフルパスを使い分けることになります。
注:手作業により既に 「オペレーションガイド」-「サンプルのデータ/プログラム」-「標準対話プログラム(msclient)」-「インデックスを作成してみる」 にてインデックス作成をおこなっています。コマンド/レスポンスの例が見られるのでそちらも合わせてお読みください
[ファイルからインデックス作成]
(形式)
CMD:"FULLPATH"にインデックス作成
FULLPATH: フルパス形式。絶対パスでも相対パスでも良い。
相対パスの場合は「ベースパス」が加算されて絶対パスとして処理される
(スクリプト例)
CMD:"sample/indexes/try/mainA"にインデックス作成
(レスポンス例)
OK:/home/foo/mshyper/sample/indexes/try/mainA(subA) 0分50秒919ミリを消費
注:インデックス作成コマンド実行後は他のCMD系コマンドは実行できません
「インデックス作成」コマンドは、現在検索パス設定して把握しているファイル群を読み出し、フィルタ処理、正規化した後、指定されたディレクトリ上にインデックスを生成します。
作成元ファイルの扱いについては「検索の仕組み」-「正規化」 を参照ください。
生成先インデックスのディレクトリ/ファイル構成は こちら を参照してください。
生成先の末尾フォルダおよびその一つ上のフォルダ(上記では try と mainA)は、もし存在しなければMindSearchが自動的に作成します。それより上位のディレクトリは実在するものでなければなりません。
指定したディレクトリに既にインデックスが存在する場合には、MindSearchはそれを一旦消去してから作業を始めます。
インデックス作成は元のファイルのボリュームが大きい場合にはかなり時間を消費します。その間、何もレスポンスが返されないので、フリーズしたと勘違いしないでください。
[上位URLを指定したインデックス作成]
Webコンテンツを意識した機能です。下記のフォーマットで上位URLを指定しておくことで(たとえば、http:// などのスキーム指定など)、ヒット情報にその文字列を含ませることができます(検索そのものに影響を与えるものではありません)。但し、検索に入る前に CMD:上位URL出力をオン を実行しておく必要があります。
(形式)
CMD:上位URL「〜」で"FULLPATH"にインデックス作成
- 「〜」: 〜は任意の文字列
検索時のモードで「上位URL出力」をオンにしておくと、
SS:レスポンスの中にこの値が記入される
(インデックス作成時のスクリプト例)
CMD:上位URL「http://」で"sample/indexes/web/mainA"にインデックス作成
(検索のスクリプト例)
CMD:上位URL出力をオン
KEY:"mind"
CMD:検索
OK:67件(精密) 67件(ラフ) 0分0秒2ミリを消費
GET:1 ↓★
SS:1|XFL|www.scripts-lab.co.jp/mindsearch/mindsearch.html|20090527105854|||http://|67|67
サンプルプログラムである sample/program/perlCGI/ または javaCGI/ 内に入っている簡易検索サイトプログラムは上のことを考慮したコーディングをおこなっています。参考にしてください。
[代替絞り込みキーについて]
テキスト本体の中に(データーベースのように)絞り込みキー情報を埋め込み、検索時にそれを指定することで、絞り込みを使った検索を行わせることができます。
本来はデーターベースモードでの検索機能強化目的で設置されたものですがファイルからの作成でも使うことができます。詳細は こちら を参照してください。
[その他のモード指定]
正規化の詳細と各種動作モード で解説しましたが、インデックスが作成される際には文字の各種正規化が行われます。希望する正規化の指定あるいはモード指定は必ずインデックス作成コマンド前に実行しておいてください。インデックス作成時のモードと検索時のモードが異なる場合、「エラーにはならないものの正しく検索されない」というやっかいな現象が出ることがありますから注意が必要です。特に、カタカナ正規化レベルの一致に注意してください。
インデックス作成コマンド(データーベースから作成) |
[インデックス作成コマンド]
(形式)
CMD:データーベース「〜」で"FULLPATH"にインデックス作成
「〜」はデーターベース名
(スクリプト例)
CMD:データーベース「Address」で"sample/indexes/db/try"にインデックス作成
(レスポンス例)
OK:/home/foo/mshyper/sample/indexes/db/try 0分5秒919ミリを消費
注:インデックス作成コマンド実行後は他のCMD系コマンドは実行できません
データーベース上に存在するデータからインデックスを作成します。ただし、MindSearchが直接にデーターベースファイルを開いて読み出すことはしません。アプリケーションからデータを「渡してもらう」方法をとります。
この方法ですと、アプリケーション側に若干のコーディング負担が及びますが、MindSearchとデーターベースとの直接のリンクが無いため、適用できるDBMSの種類やバージョンを選ばないほか、データーベースに限らず「ダイナミックに沸いてくる」ようなデータすべてをインデックス化できる利点があります。
データーベースのデータは物理ファイルとして置かれているものではないため on-the-fly でインデックスを作ります。手法としては、アプリケーションが目的のデーターベースに接続してオープンし、全レコードについてそのプライマリキーとテキストデータのペアを次々とMindSearchに「投げ」ます。MindSearchはソケットから受け取ったデータを元に次々とインデックス作成するという仕掛です。
アプリケーションではそのための小さなルーチンを組む必要がありますが、データベースのプログラミングに慣れた開発者であれば恐らく十数行で書けてしまう程度と思われます。
[インデックス作成の詳細]
アプリケーションとMindSearchとは次のような手順でデータ渡しを行ないます。
アプリケーション発データ |
方向 |
MindSearchコア発データ |
CMD:データーベース「Address」で
"sample/indexes/db/try/mainA"に
インデックス作成 |
→ |
|
|
|
|
|
← |
REQ |
PUT:append|プライマリキー|レコードID|
ソートキー1|ソートキー2| ... |ソートキー9|
絞り込みキー1|絞り込みキー2| ... |絞り込みキー4 |
→ |
|
|
← |
REQ |
PUT:テキスト |
→ |
|
|
← |
REQ |
PUT:テキスト(2) (テキストが4096バイト超の場合) |
→ |
|
|
← |
REQ |
PUT:テキスト(3) (テキストが4096バイト超の場合) |
→ |
|
|
← |
REQ |
PUT: |
→ |
|
|
|
|
|
← |
REQ |
PUT:append|プライマリキー|レコードID|
ソートキー1|ソートキー2| ... |ソートキー9|
絞り込みキー1|絞り込みキー2| ... |絞り込みキー4 |
→ |
|
|
← |
REQ |
PUT:テキスト |
→ |
|
|
← |
REQ |
PUT:テキスト(2) (テキストが4096バイト超の場合) |
→ |
|
|
← |
REQ |
PUT:テキスト(3) (テキストが4096バイト超の場合) |
→ |
|
|
← |
REQ |
PUT: |
→ |
|
|
|
|
|
← |
REQ |
PUT: |
→ |
|
---長い処理時間--- |
|
|
|
← |
OK:/home/foo/mshyper/sample/indexes/db/try 0分5秒919ミリを消費 |
上の図を解説します。まず「インデックス作成」コマンドを送信すると、MindSearchは直ちに「REQ」というレスポンスを返して来ます。これは「Data Request」の略です。
アプリケーションは、最初のレコードのヘッダとして
PUT:append|プライマリキー|レコードID|ソートキー1|..ソートキー9|絞り込みキー1|..絞り込みキー4
を1パケットで送信します。不要な項目は空文字とするかあるいは後半が全部不要なら'|'記号も省略できます。
MindSearchから再び「REQ」が返されます。
アプリケーションはレコードのデータを送信します。但し通信バッファの最大長が4096バイトに制限されているため、大きなデータは複数に分割して送信します。上記例では3回に分けてデータを送出しています。これによりいくらでも長いテキストデータでも送出が可能になります。データの最後には PUT: だけのパケットを送出します。
(例(テキストを1パケットで送出できる場合))
REQ
PUT: ポーランドに住むベロニカは天上からの賜物としかいえない美しい歌声を持つ。ある
日、街に出ると広場はデモに集まった群衆や観光客で騒然としていた。その群衆の中に
、自分とそっくりな若い女性を見つける。(いつも自分は、ひとりじゃないと感じてい
たけれど・・・・)と彼女はびっくりする。が、その女性は彼女に気づかずバスに乗っ
ていってしまう。ただバスのなかから広場の群衆をカメラに撮りながら・・・・・。
あとでそのフィルムを現像してみると自分にそっくりな女性が写っているのでびっくり
するという符号になっているのだが、このシーンではまだそこまではわからない。ただ
、二人のベロニカは、こうして生前に一度だけ擦れ違っている。
REQ
PUT: ←テキスト分割の最後
MindSearchから再び「REQ」が返されます。
先と同様に、今度は第二レコードのヘッダとして「PUT:append|プライマリキー|レコードID|・・」を第一パケットで送信し、次にデータを第二パケットで(長い場合はさらに続くパケットで)送信します。
全レコードの送出が終わったら、アプリケーションは PUT: だけの送信を行ないます。MindSearchはこれを見てすべてのレコードの終わりであると判断し、内部的なインデックス作成に入ります(この先は時間がかかります)。
(例)
PUT: ←全レコード終了の通知
しばらく経過すると「OK:」が送られてきて処理は終わりです。
注1:エンジンから返される REQ は、このタイミングで必ず REQ が来ると仮定しないでください。何らかのエラーが有った時は(ヘッダのフォーマット間違いなど)NG:メッセージ 形式のエラーメッセージが返されることがあります。頻繁に到着する REQ ですが、すべての受信場面で「本当にREQであるか」のチェックを行うようにしてください。このチェックをしない場合、エンジンは NG:メッセージ を返したあと次のコマンド待ちになっているにもかかわらず、アプリケーションは依然として PUT: コマンドを送り続けることになります。
注2:Java, Perl, PHPの通信ライブラリを使う場合はPUTコマンドのデータ長の制限はありません。通信ライブラリ内部で複数のPUTコマンドに自動分割して送信します。但しこの場合であっても、テキスト部の終わりを示す空のPUTコマンドは明に送出する必要があります。
注3:データにマルチバイト文字が含まれる場合であっても、マルチバイトの分断を気にせずに丁度4096バイトで切って構いません。MindSearchの側では複数のPUTコマンドで到着したデータを個々に処理せず、一旦結合してから処理を行なうようになっています。
注4:ファイルからインデックスを作成する場合には自動文字コード認識がおこなわれますがデーターベースからの作成時には行なわれません。決められた文字コードを与えるようにしてください(文字種については「CHR」コマンド(文字コード指定)」を参照してください)。
[アクションについて]
上の例でヘッダを送出するパケットの先頭に「append」が記入されていますが、これをアクションと呼んでいます。以下の種類があります。
append ←レコードの追加
update ←レコードの更新
delete ←レコードの削除 注:テキストのパケットは送出しない
主インデックス(初回)の作成ではアクションは常に append を指定してください。
差分インデックス作成では上記3種のいずれもが使えます。但し、delete の場合にはテキスト対応のパケットは送出しないでください(ヘッダだけを送出)。
[「レコードID」について]
インデックス作成時に、アプリケーションからMindSearchにプライマリキーと共にレコードIDと称するものを送ることができます。ヒットセンテンスの情報が返されるとき、SS:レスポンスの中にこの情報が記入されます。たとえば、
SS:1|XDB|eigaDB|eiga-1|RECID1|20031216010201|sub|1|1
上記太字の部分がそれです。MindSearchは単に記憶したものを返しているだけで、それ以上の意味はありません。アプリケーションはこれも何らかの目的のために使うことができます。不要であれば空文字を与えておいてください。
[ソートキータイプ設定]
ソートキーを投入する場合、インデックス作成コマンドの実行に先立ってソートキーのタイプを指定しておく必要があります。
(文法)
CMD:「<タイプ列>」をソートキータイプ設定
- タイプ列は1〜9桁の英字列
1桁目がソートキー1、9桁目がソートキー9のタイプを表わす
- インデックス作成コマンドより前に実行しておく(必須)
- デフォルトは無い(最低でも1キー分は指定すること)
D 日付(フォーマット詳細は 日時情報について< 参照)
N 整数
S 文字列
(例)
CMD:「D」をソートキータイプ設定
CMD:「DNNNSSSSS」をソートキータイプ設定
[絞り込みキータイプ設定]
絞り込みキーを投入する場合、インデックス作成コマンドの実行に先立って絞り込みキーのタイプを指定しておく必要があります。
(文法)
CMD:「<タイプ列>」を絞り込みキータイプ設定
- タイプ列は1〜4桁の英字列
1桁目が絞り込みキー1の、4桁目が絞り込みキー4のタイプを表わす
- インデックス作成コマンドより前に実行しておく
- 専用絞り込みキーを使わない場合は実行不要
R 範囲指定可能な整数 (検索時に意味がありインデックス作成時はNと同じ効果)
N 整数
S 文字列
(例)
CMD:「NNSS」を絞り込みキータイプ設定
ソートキー1から絞り込みキー1への自動転写
特別な使い方として下のようなものがあります。
(文法)
CMD:「<タイプ列>/D」を絞り込みキータイプ設定
(例)
CMD:「RNSS/D」を絞り込みキータイプ設定
上のようにタイプ列の末尾に「/D」を指定すると、インデックス作成時、ソートキー1の値が絞り込みキー1に強制的に転写されるようになります(PUTコマンド中の絞り込みキー1は無視されます)。これは日時の複写を行うためのもので、検索時に日時による絞り込みを可能とします。
この形式を使う場合、ソートキー1の型が「D」、絞り込みキー1の型が「N」または「R」である必要があります(絞り込みキー1を'R'にしておくと検索時に範囲指定の絞込みができます)。それ以外のケースではエラーになります。
[代替絞り込みキーについて]
前記した専用の絞り込みキーを使うほかに、テキスト本体の中に絞り込みキー情報を埋め込み、検索時にそれを指定することで、結果として専用絞り込みキーと同様の働きをさせることができます。どちらが優れているというものではなく、長所・短所があります。
代替絞り込みキーが記入されたテキストをインデックス作成する場合には予め次のコマンドを実行しておく必要があります。インデックスの中に必要な情報が生成され検索時に使われます。(この指定をしたからといって全レコードに代替絞り込み行を付与する必要はなく、一部のレコードのみに含ませるのでも構いません)
(文法)
CMD:代替絞り込み使用をオン ←ファイルからのインデックス作成でも使えます
サンプルテキスト群の一つに、sample/texts/eigaAltKey/ というフォルダがありますが、これは代替絞り込みキーのテストのために置かれているものです。この中の一つ eiga2.txt の先頭部は次のようになっています。
----------------------------------------------------------------
_AREA_大阪_ _SIZE_m_ _AT1_abd_ _AT2_abce_ _AT3_deg2_
政治的に大きな変動のあったポーランドは、まだ訪れたことのない地だが、
〜略〜
----------------------------------------------------------------
先頭1行が代替絞り込みキーの列挙になります。この行の左右の端は必ず記号 '_' を置く必要があります。
空白で区切った複数のトークンが記述されていますが、一つ一つのトークンが属性名と属性値のペアとなります。このうち一つを検索時に(普通のキーワードのように)指定することで絞り込みを行わせることができます。
最初の一つが「_AREA_大阪_」ですが、「AREA」が絞り込みキーの属性名、「大阪」がその値に相当します。
属性名、属性値とも表記や長さは自由ですが、左右端は必ず記号 '_' が置かれるようにしてください。
検索時の事項については 検索系コマンド − 代替絞り込みキーを使う検索 を参照してください。
[日時情報について]
レコード毎に日時情報(タイムスタンプ)を入れたい場合には、ソートキーの一つ(キー1を推奨)に記入してください。さらには、絞り込みキータイプ設定コマンドの中で「/D」を指定することで、そのソートキー1を絞り込みキー1に自動的に転写することもでき、これを使えば検索時に日時による絞り込みを行うことが容易になります。
上に述べたように日時はソートキーの一つとして記入してください。また対応するソートキータイプ設定では「D」型を指定してください。日時情報は以下のいずれかのフォーマットで記入してください。
(数字表現)
20020509 ← 8桁(年・月・日) (時刻は00:00:00と解釈されます)
20020509123456 ←14桁(年・月・日・時・分・秒)
(英語表現)
Wed, 29 Mar 2000 12:58:02
29 Mar 2000 12:58:02 ←曜日は省略可
Sat Nov 11 22:31:15 2000
後者の英語表現は、メールのヘッダ部にあるDate:、あるいは、HTTPヘッダのDate:にある情報をそのまま伝えられるようにしたものです。なお、HTTPヘッダのDate:はGMT表現であることが多く、その場合には、MindSearchの側で+9時間を補正します(MindSearch内部ではローカルタイムとして記憶します)。
[その他のモード指定]
正規化の詳細と各種動作モード で解説しましたが、インデックスが作成される際には文字の各種正規化が行われます。希望する正規化の指定あるいはモード指定は必ずインデックス作成コマンド前に実行しておいてください。インデックス作成時のモードと検索時のモードが異なる場合、「エラーにはならないものの正しく検索されない」というやっかいな現象が出ることがありますから注意が必要です。特に、カタカナ正規化レベルの一致に注意してください。
[差分インデックシング]
末尾フォルダを「mainA」のように指定することで通常の主インデックスが作成されます。「subA」のように指定するとその前におこなった主インデックスに続く副インデックス作成として扱われます。
多くのケースで、A/B系統はMindSearchの自動判別に任せるのが良いでしょう。つまり、末尾フォルダ名は「mainS」「subS」のように指定することを勧めます。
(スクリプト例1)
CMD:"sample/indexes/try/subS"にインデックス作成
Sを指定すると、MindSearchは現在ロードされている共有メモリの情報を見てA/B系統を判断します。主インデックス作成時には現在ホットな系統と逆のほうに生成するようにします。副インデックス作成時にはそれだけでなく、A/Bどちらの主インデックスが自分にとっての「親」なのかを識別する機能もあります。
当該インデックスが共有メモリにロードされていない場合、MindSearchは別の方法で生成系統を判断します。但し、subに対してはそのペアとなるmainの決定ロジックがそれほど完璧ではないため、sub指定時に「親となるmain」を明に指定することもできます。
(スクリプト例2)
CMD:"sample/indexes/try/subB(mainA)"にインデックス作成
(スクリプト例3)
CMD:"sample/indexes/try/subS(mainA)"にインデックス作成
何回も差分インデックシングを繰り返すと副インデックスのサイズが大きくなり、ディスク消費や検索時間の増大を招くため適当なタイミングで全体のインデックス作成をやり直す必要があります。(主インデックス作成を行なうと副インデックスサイズはゼロとなります)。副インデックスのサイズ(あるいは件数)が主インデックスの三分の一程度になったら主作成をおこなうことをお勧めします。
[擬似的なデーターベースのインデックス作成]
mscilent の特別な機能を使い擬似的に(但しMindSearchとの交信手順は正式です)インデックスを作成できる仕組みがあります。
まず、msdaemonを立ち上げておいてください。
次にシェルスクリプト make-eigaDB.sh を実行します(以降の検索テストでも使うので本当に作成してださい)。
$ ./make-eigaDB.sh
msclient: start
msclient: Host:localhost Port:3515
"makeindexDBfull.hist"を履歴ファイルとして読み込みます。
MindSearchエンジンとの対話開始
_ ←キー入力待ち
上記のように msclient の立ち上がりメッセージが表示され、キー入力待ちとなります。
まず「?」コマンドを入力してこれから送出されるスクリプトを確認します。
? ←キー入力
1 INI:app01
2 STA
3 CMD:「DNNNSSSSS」をソートキータイプ設定
4 CMD:「RNSS/D」を絞り込みキータイプ設定
5 db:eigaDB sample/texts/eigaDB sample/indexes/eigaDB/mainA
_ ←キー入力待ち
上記の通り簡単なものです。
「db:」というコマンドはMindSearchのものではなく、msclient自身が持つコマンドです。(MindSearchのAPIと区別できるよう自身のコマンドはすべて小文字になっています)
db:コマンドは引数を3つ持ちます。1番目がデーターベース名(のつもり)、2番目がテキストファイルが格納されているディレクトリ、3番目がインデックスファイルを生成するディレクトリです。
msclient はプレーンテキストを読み込み、MindSearchに対してはあたかもデーターベースから取り込んだデーターであるかのような振りをして交信し、インデックスを作成する仕掛になっています。この方式であれば、テキストファイルさえあればデーターベース形式のインデックスを作れるため、アプリケーションが組めるようになるまでのつなぎ(検索向けプログラムを先行するなど)として使えます。
以下のように、1〜5番のコマンドを一度に実行します。
1-5
send=INI:app01
recv=OK:app01002466240
〜略〜
send=CMD:「DNNNSSSSS」をソートキータイプ設定
recv=OK:
send=CMD:「RNSS/D」を絞り込みキータイプ設定
recv=OK:
〜略〜
send=CMD:データーベース「eigaDB」を"/home/foo/mshyper/sample/indexes/eigaDB/mainA"にインデックス作成
recv=REQ
send=PUT:append|eiga-4|RECID4|20031218010204|003|08|996|porland|noun|IRU|so‥
.recv=REQ
send=PUT: ポーランドに住むベロニカは天上からの賜物としかいえない美しい歌声‥
recv=REQ
send=PUT:
.recv=REQ
send=PUT:append|eiga-2|RECID2|20031215010202|002|08|998|seijiteki|adj|NAI|s‥
recv=REQ
send=PUT: 政治的に大きな変動のあったポーランドは、まだ訪れたことのない地だ‥
recv=REQ
send=PUT:
recv=REQ
send=PUT:append|eiga-7|RECID7|20031214010207|007|02|999|eiga|noun|ru
recv=REQ
send=PUT:映画評論の付加ファイル。
差分更新時にdeleteされる。
recv=REQ
send=PUT:
recv=REQ
send=PUT:append|eiga-3|RECID3|20031217010203|004|11|997|europe|noun|YOU|sor‥
recv=REQ
send=PUT: ヨーロッパ映画といえば昔から、湿潤な邦画にはとても手が出せない独‥
recv=REQ
send=PUT:
recv=REQ
send=PUT:append|eiga-1|RECID1|20031216010200|001|07|999|watasi|noun|KII|sor‥
recv=REQ
send=PUT: 1.ふたりのベロニカ 片桐 真喜‥
recv=REQ
send=PUT:
recv=REQ
send=PUT:
recv=OK:/home/foo/mshyper/sample/indexes/eigaDB/mainA(subA) 0分57秒328ミリを消費
PUT:コマンドによるデーターの送出は量が多いため、msclient側の仕様として途中からモニタ表示を省略するようになっています。実際には上の図よりも多いデータが送信されています。
次に、上記で作成された主インデックスを使い、差分インデックシングをおこなってみます。今度は対話に入らずに一気実行とします(-exec オプションでそのようになります)。
$ ./make-eigaDBupdate.sh -exec
msclient: start
msclient: Host:localhost Port:3515
send=INI:app01
〜略〜
send=CMD:「DNNNSSSSS」をソートキータイプ設定
recv=OK:
send=CMD:「RNSS/D」を絞り込みキータイプ設定
recv=OK:
send=CMD:データーベース「eigaDB」を"/home/foo/mshyper/sample/indexes/eigaDB/subA(mainA)"にインデックス作成
〜略〜
recv=OK:/home/foo/mshyper/sample/indexes/eigaDB/subA(mainA) 0分24秒737ミリを消費
インデックス生成先を確認するために、msindexinfo を使ってみます。わざと基幹パスを与え、主・副インデックスを両方表示させます。
$ msindexinfo sample/indexes/eigaDB
/home/foo/mshyper/sample/indexes/eigaDB/mainA
==ドキュメントプロパティ==
マーク=0x46 ('F'=0x46であるはず)
状態=2 (0:アイドル 1:ビジー 2:完了)
エンディアン=0 (1:BigEndian; 本マシンのBigEndian=0)
文字種=E ('S'jis , 'E'uc , 'J'is のいずれか)
フェーズ数=10
ドキュメント数=5 グループ数=1 グループ端数=5 グループ要素数=100000
主副識別コード=1
物理ファイル=0 (0:データベースから生成 1:ファイルから生成)
IndexVersion=63
許可ProgVer最低/最大=63/64 拒否ProgVer最低/最大=00/00
BasePath/DB名=eigaDB
上位URL=
作成日時=2009-06-04 11:21
作成時の検索正規化フラグ =061A
作成時のカタカナ正規化レベル=1
作成時のカタカナ正規化フラグ=0000003F
ソートキー数=9 ソートキータイプ=DNNNSSSSS 絞り込みキータイプ=RNSS
正規化グループサイズ=2390
TotalDocuments=5
/home/foo/mshyper/sample/indexes/eigaDB/subA
==ドキュメントプロパティ==
マーク=0x46 ('F'=0x46であるはず)
状態=2 (0:アイドル 1:ビジー 2:完了)
エンディアン=0 (1:BigEndian; 本マシンのBigEndian=0)
文字種=E ('S'jis , 'E'uc , 'J'is のいずれか)
フェーズ数=10
ドキュメント数=3 グループ数=1 グループ端数=3 グループ要素数=100000
主副識別コード=2
物理ファイル=0 (0:データベースから生成 1:ファイルから生成)
IndexVersion=63
許可ProgVer最低/最大=63/64 拒否ProgVer最低/最大=00/00
BasePath/DB名=eigaDB
上位URL=
作成日時=2009-06-04 11:29
作成時の検索正規化フラグ =061A
作成時のカタカナ正規化レベル=1
作成時のカタカナ正規化フラグ=0000003F
ソートキー数=9 ソートキータイプ=DNNNSSSSS 絞り込みキータイプ=RNSS
正規化グループサイズ=4140
TotalDocuments=3
同様にして「特許の話」は make-tokkyoDB.sh を起動することでおこなえます。
(主index)
$ ./make-tokkyoDB.sh -exec
↑これを付けると対話に入らずに一気に実行します
(差分作成)
$ ./make-tokkyoDBupdate.sh -exec
以上でインデックスが生成できたので試しに eigaDB を検索してみてください。
(インデックスを共有メモリにロード)
$ msctrl load @symeigaDB sample/indexes/eigaDB
MSdaemon: detect SUS -> stop listen
msctrl: request: load /home/foo/mshyper/sample/indexes/eigaDB
〜略〜
msctrl: OK:
MSdaemon: detect RES -> resume listen
$ msctrl load @symtokkyoDB sample/indexes/tokkyoDB
MSdaemon: detect SUS -> stop listen
msctrl: request: load /home/foo/mshyper/sample/indexes/eigaDB
〜略〜
msctrl: OK:
MSdaemon: detect RES -> resume listen
(対話に入る(簡易型スクリプト使用))
$ ./sch.sh symeigaDB
1-5
send=INI:app01
recv=OK:app01001676239
〜略〜
send=CMD:インデックスをつかい"symeigaDB"を検索パス設定
recv=OK:#1
send=KEY:"映画"and"監督"
recv=OK:
send=CMD:検索
recv=OK:2件(精密) 2件(ラフ) 0分0秒1ミリを消費
[擬似データーベース向けのデータフォーマット]
msclientの db コマンドを使って擬似的にデーターベース形式でインデックシングする際のデータフォーマットについて説明します。
- データはプレーンテキストとして用意しておく。指定した格納元ディレクトリ内にある全ファイルがスキャンされ、1ファイルが1レコードとなる
- 先頭行に'|'が存在し、その第一項がMindSearchに向けてのPUTコマンドの形式に合致しているなら、その行をそのまま先頭PUTデータ(プライマリキー等のパケット)とし、2行目以降をデータ・ボディとして扱う
- 上記に合致しない場合はテキストファイル全体をボディとして扱う。この場合、1から始まる数字を自動生成してプライマリキーとし、ファイル名から上位パスと拡張子を取り除いた主ファイル名部をレコードIDとする。
先に実際のインデックス作成例を示しましたが、sample/texts/eigaDB/ 下に格納されているファイルは前述 2. に該当するものです。たとえば、eigaDB/eiga2.txt は以下のような内容になっています。
------------------------------------------------------------------------------
append|eiga-2|RECID2|20031215010202|002|08|998|seijiteki|adj|NAI|sort87|sort92|10|20|横浜|aa
政治的に大きな変動のあったポーランドは、まだ訪れたことのない地だが、全体をセ
ピアのクラシカルな色調の中で描き、はかなさと淡い期待を、隅々まで静謐に含んだ映
像が新鮮だ。
クシシュトフ・キェシロフスキは、かつて「殺人に関する短いフィルム」や「愛に関
する短いフィルム」でセンセーショナルな注目を集めたが、今度の「ふたりのベロニカ
」はそれらとはまったく違った、優しく幻想的なファンタジーなのである。体制が激変
したことと決して無関係ではないという、この一つの芸術作品を私は讃えずにはいられ
ない。
------------------------------------------------------------------------------
上記のように1行目はPUTデータそのものになっています。これが、eiga/ 内コンテンツと eigaDB/ 内コンテンツの違いです。sample/texts/tokkyoDB/ (特許の話) も同様です。
次に、eigaDB2/ 内ファイルについて説明します。これは先の eigaDB/ を使ったインデックシングに引き続いて行なう差分インデックシングのためのデータで以下のファイルが含まれています。
eiga1u.txt ←eigaDB/eiga1.txt のupdate(更新)用
eiga5a.txt ←appendレコード
eiga6a.txt ←appendレコード
eiga7d.txt ←deleteレコード
ちなみに eiga7d.txt の中身は 「 delete|eiga-7 」が1行だけ格納されておりテキストが有りません。delete指令はプライマリキーのみが有れば良くテキストを必要としないためです。(API仕様上もテキストを送信してはならないことになっています)
モニタ機能
「インデックス作成」コマンド送出から「OK:」レスポンス受信までの間は長い時間何も起きないためエンジン内部の進行状況が分かりませんが、この間、MindSearchにモニタ表示をさせることができます。
モニタ表示は msdaeon を起動した時のコンソールに表示されるため、起動時のコンソールが閉じてしまっている場合には、一旦停止させて再度起動しなおしてください。msclient などアプリケーション側のプログラムの起動にはさらに別のコンソールを使えばエンジンからのモニタ表示とアプリケーション側の表示が混ざらなくてすみます。
モニタ表示には以下の方法があります。いずれもタッチファイル(中身が空のダミーファイル)を bin/ ディレクトリ直下に置きます。これらのファイルはインストール後既にに存在していますが、ファイル名末を"NOT"とすることで無効化してあります。末尾"NOT"を外した名前にリネームすることで有効化できます。
タッチファイル |
機能 |
_monitor_idxprogress_ |
インデックス作成全体の進行状況を表示します |
_monitor_DBheader_ |
データーベースモードでのインデックス作成時、アプリケーションから受け取ったヘッダ行を表示します。 ヘッダ解析後の情報であるため、たとえば'|'の数を間違えたなどのミスの発見にも役立ちます。 |
タッチファイル方式とは別に: デーモンの起動を「msdaemon -m &」とすることで(-mを指定)エンジン全体がモニタモードとなり、各種情報を表示します。情報量が多くなるため、多量のデータのインデックス作成の表示には向いていません。 |
注: ファイルからのインデックス向けでありデーターベースからインデックスを作成する場合は関係ありません
フィルタ定義ファイル
MindSearchの ディレクトリ構成図 で解説されている「フィルタ定義ディレクトリ(filterdef/)」にはフィルタ定義ファイルと呼ばれるファイル群が格納されます。
フィルタ定義ファイルは物理ファイルからのインデックス作成において、ファイルの拡張子と、それにどのようなフィルタ(プレーンテキスト抽出プログラム)を適用するかの対応を表で保持するものです。
フィルタ定義ファイルの明示
インデックス作成においてフィルタ定義ファイルを特に指定しない場合、default.def が使われますが、次のコマンドにより定義ファイルを明示できます。
(形式)
CMD:"FILENAME"をフィルタ定義ファイル設定
FILENAME: パスは付けない。拡張子は'.def'必須
(スクリプト例)
CMD:"webcontents.def"をフィルタ定義ファイル設定
(レスポンス例)
OK:webcontents.def
インデックス作成時に適用されたフィルタ定義が何だったのかはログから知ることができます。log/process.log に以下のような情報が記入されています。
<process.log>
----------------------------------------------------------
2009-06-05 15:43:07 MSmkindex: Filtr: idx=/home/foo/mshyper/sample/indexes/te
stpdf/mainA filterdef=filterdef/html.def
----------------------------------------------------------
フィルタ定義ファイルの記述ルール
標準の default.def の内容は次のようなものです。
<default.def>
----------------------------------------------------------
txt plain
html html
htm html
shtml html
cgi html
pl html
asp html
php html
----------------------------------------------------------
1行に2語が並んでいます。
第一語はファイルの拡張子名です。検索対象となるファイルはその拡張子によって分類されますが、そのための情報になります。拡張子の大文字・小文字は区別されません。
注:拡張子リストのいずれにも該当しない拡張子を持つファイルはMindSearchにとっては「見えないファイル」になります。さらには(以下で述べますが)フィルタが必要な拡張子であるにもかかわらず対応フィルタが存在しない場合もそのファイルは「見えないファイル」となります。
第二語はファイルの分類名になります。よく使われる名称が付与されています。「plain」は予約語でプレーンテキストを表わします。「plain」以外のものは「プレーンテキストではないもの」とみなされ、そのファイルに対してフィルタ(変換プログラム)を通すことでプレーンテキストを得ます。
ちなみにこの分類名の頭に「mf」を付加したものがフィルタプログラム名になります。たとえば、"html"という分類名に対しては"mfhtml"という名称のフィルタ・プログラムがその変換のために使われます。つまり分類名はフィルタプログラム名を決定するのにも使われることになります。
分類名が「plain」の場合には、第三語として「nocheck」という語を置くこともできます。たとえば次のような記述になります。
----------------------------------------------------------
txt plain nocheck
----------------------------------------------------------
第三語として nocheck が書かれている場合、このプレーンテキストは文字種判定処理をスキップし、MindSearchが走行しているOSのネイティブな文字種(UNIXであればEUC-JP)であると想定した動作をします。文字種判定処理を省くことができるので処理が早くなりますが、その代わりに、うっかり異なる文字種を含むテキストファイルが存在した場合に文字化けを起こしそのファイルは検索できなくなります。トレードオフなので開発者の判断で選ぶことになります。
以下のようなワイルドカード(*)が使えます。ファイル名をまったく照合せず、すべてHTMLファイルである場合に使えます。
----------------------------------------------------------
* html ←ここまででマッチしないすべての拡張子をマッチさせる
----------------------------------------------------------
特殊な指定
フィルタ定義ファイルの内容に以下の特殊な指定をおこなうことができます(1行に1語)。
----------------------------------------------------------
allownoext ←拡張子無しファイルをhtmlと想定する
allowcgiargs ←CGI引数(〜〜?〜〜)をhtmlと想定する
----------------------------------------------------------
上記を使った例として、Webサイトのミラーを丸ごとインデックシングするための定義ファイルの例を以下に示します。
<webcontents.def>
----------------------------------------------------------
txt plain nocheck
allownoext
allowcgiargs
html html
htm html
shtml html
cgi html
pl html
asp html
php html
----------------------------------------------------------
標準装備以外のフィルタを使うには
HTMLフィルタのみが標準装備となっています。
前記でファイル種別の頭に「mf」を付加したものがフィルタプログラム名になると書きましたが、厳密には開発者が独自に用意したフィルタを使う場合には、頭に「mf」を、末尾に「.sh」を付加したものがフィルタプログラムとして扱われます。
たとえば、"pdf"という分類名に対しては"mfpdf.sh"という名称のフィルタ・プログラムがその変換のために使われます。これはシェルスクリプトとし、このスクリプトの中から本来のテキスト抽出プログラムを呼び出すことになります。フィルタの呼び出し時の引数を統一させるためこのような間接的な方法をとっています。
フィルタは(正確にはフィルタ呼び出しのシェルスクリプトは)bin/ ディレクトリ内に置いてください。引数はコマンドライン形式で書けば、
mfxxx.sh INFILE OUTFILE
という仕様です。たとえば mfpdf.sh は以下のような簡単なものを用意すれば良いでしょう(当然ですが別途、フリーソフトの pdftotext をインストールしておく必要があります)。
<mfpdf.sh>
----------------------------------------------------------
#!/bin/sh
/usr/local/bin/pdftotext -enc EUC-JP -raw $1 $2
----------------------------------------------------------
MindSearchはフィルタを呼び出した後、変換元のタイムスタンプを変換後のファイルに改めて打ち込み、タイムスタンプを維持します。したがってフィルタ側でそのようなことをおこなう必要はありません。
ファイルからのインデックス作成に msclient をアプリとして使う |
注: ファイルからのインデックス向けでありデーターベースからインデックスを作成する場合は関係ありません
インデックスを作成するには、本来はMindSearchのAPIを使ったアプリケーションを組む必要があるのですが、ファイルからのインデックス作成でかつ定型で簡単なもので良いのなら、アプリケーションを組まなくとも対話用ツールである msclient をバッチモードで使うことでUNIXのコマンドのように使うことも可能です。このセクションではその方法を示します。
msclient の起動方法は既に 「開発関連ツールの使い方」−「msclient(標準対話プログラム)」 にて解説済みですが、その中の -exec および -e オプションの使い方をここで補足します。両オプションに注目した起動方法は以下の通りです。
(文法)
$ msclient -exec -eARG1:ARG2:ARG3:..ARG6 HISTORYFILE
-exec ←バッチモードで起動するためのオプション指定
-eARG1〜ARG6 ←ヒストリ内に可変部があればその実値を指定
HISTORYFILE ←実行すべきヒストリファイル名
例えば次のようなヒストリファイルがあると仮定します。
(testmake.histの内容)
36
INI:app01
STA
CMD:"(here1)"を検索ベースパス設定
CMD:"+"を検索パス設定
CMD:"(here2)/mainS"にインデックス作成
上記のヒストリファイルと組み合わせて以下のような実行方法が考えられます。
(msclientの実行例)
$ msclient -exec -e/data/text/cars:/data/index/cars testmake.hist
上記のような起動を行うと、msclientが起動した直後、ヒストリファイル中の (hereN) の部分が -e オプションの指定により置換され、最終的に以下のようなコマンド群が実行されます。
(最終的に実行されるコマンド群)
INI:app01
STA
CMD:"/data/text/cars"を検索ベースパス設定
CMD:"+"を検索パス設定
CMD:"/data/index/cars/mainS"にインデックス作成
一方、-exec オプションは、msclient起動後に対話に入らずに、直ちにヒストリファイル内容をすべて実行するという意味であり、msclientをバッチで実行するのに使えます。
さらには、このような msclient の起動をシェルスクリプトとしておくことにより、あたかも特定のインデックス作成を行うプログラムが存在するかのようにできます。
msclientが正常終了なら 終了コード=0、エラーなら ≠0 の値を返すので上位プログラムから msclient (あるいはそれをキックするシェルスクリプト)の終了状態を検出することも可能です。
なおmsclient走行中の画面への情報出力を避けるには以下のいずれかの方法があります。
(方法1)
$ msclient -exec -e/data/text/cars:/data/index/cars testmake.hist > /dev/null
出力を単に捨てる↑
(方法2)
$ msclient -exec -e/data/text/cars:/data/index/cars testmake.hist > _msclient_result_
出力をファイルに落とす↑
後者はリダイレクト先を作業ログとして参照できるため開発段階では便利です。
Copyright(C) 2000-2009 Scripts Lab. Inc.