ツッコめ!全文検索エンジンSennaの新しいAPIについての素案。

みんな、[Senna-dev 884]のメールは読んだかな!?
全文検索エンジンSennaの新しいAPIについての素案がついに公開されました。


今までのAPIのほとんどを刷新するという
大改造!劇的ビフォーアフターAPI群です(APIの匠)。


んで、この新しいAPI群で何ができるようになるのでしょうか。
簡単に言うと、
Sennaは、データベースになります!」


といいつつも、全文検索機能を充実させるために、
データベース的機能を強化した、という感じになっておりますぞ。

データベース機能

新しいSennaでは、複数のテーブルというものを持つことができます。
テーブルは、複数のレコードを持つことができます。
レコードは、複数のカラムを持つことができます。
カラムは、ある型のデータを保持します。
一般的なRDBMSの2次元表をまずはイメージしてください。

ポイント1. レコードごとにカラムが追加できる

Sennaの新しいAPI群では、レコード毎にカラムを追加することができます。
というわけで、二次元表ではなく、穴あきの二次元表をイメージするとよいでしょうか。

もちろん、あるカラムでの絞込みやソート、グループ化などの操作も行うことができます。

ポイント2. 外部参照が高速

いわゆる外部参照が高速に行える実装となっております。
具体的にいうと、カラムに保持する型として、他のテーブルそのものを指定することができます。
このように指定されたカラムは、他のテーブルへの参照を保持します。

ポイント3. 強力なフック

テーブル・カラムを参照もしくは更新するタイミングで、
任意の関数を呼び出すことができます。
トリガーのようなものです。
この関数で、値をフィルタしたり、値を横取りしたり、
そもそもイベントそのものを握りつぶしたりすることができます。


以上の3つのポイントが大きな特徴となっております。


それ以外にも、テーブルのタイプが3つあったり、
テーブルを物理ファイルにマップするか、メモリ上だけに作るか選べたり…
などいろいろ特徴がありますが、
大雑把に説明するとこんな感じです。

全文検索インデックスの拡張

今までのSennaでは、
主にsen_indexという型についての操作を行うことによって、
全文検索インデックスへの操作を行っていました。


sen_indexは、内部的には以下の3つの構造から成り立っています。


文書ID表は、Senna内部での文書ID番号と、外部での文書IDとの対応付けをするための表です。
外部での文書IDの実例として、
TritonnであればMyISAMのレコード位置、
Ludiaであればtuple idが挙げられます。


語彙表とは、文書内に登場する単語がすべて登録され、それぞれに語彙ID番号が対応付けされている表です。
N-gramを語彙とするのであれば、1または2文字の文字列が語彙表に登録され、
MeCabで切り分けられた形態素を語彙とするのであれば、形態素が語彙表に登録されます。


転置インデックスとは、
語彙ID番号ごとに検索データを保持するデータ構造です。
ある語彙を含む文書について、Senna内部での文書ID番号の列を語彙ごとに保存しています。
(本当はもうちょっと情報を保持しているのですが、説明の簡単化のため省略)


この3つの構造を用いることによって、全文検索を行うことができます。
具体的には、
「検索キーワード」→
「検索キーワードの語彙ID番号」→
Senna内部での文書ID番号の列」→
「外部での文書ID番号の列」
のように順番に表を引くことにより、検索結果の文書ID群を得ることができるわけです。


Sennaの新APIでは、ID表と語彙表について、Sennaデータベースのテーブルを用いることができます。
転置インデックスのみ、inv index columnという特殊なカラムが用意されています。


ID表と語彙表が一般的なテーブルとなったということは、
それぞれのレコードに好きなカラムを追加できるということです。


ID表にカラムを追加することにより、こんなことが出来るようになるでしょう。

  • 日付カラムを追加して、その日付での高速な絞込み・ソート・グループ化
  • 無効化フラグを追加して、検索結果から即時に除外をする

…つまり、

  • 文書ごとに複数の属性値が保存できる
  • 属性値で絞込み・ソート・グループ化ができたり、フックを用いてさまざまな操作を行ったりできる。

の2つの併せ技で出来ることが増えるというわけなのです。


語彙表にカラムを追加することによって、こんなことが出来るようになるでしょう。

  • query式を用いた場合でもTF-IDFによるスコア計算を可能に
  • 検索ストップワードなどの実現
  • ある語彙に関してのスコアだけを上下する操作
  • 文書登録日別の語彙の総出現数をカラムに追加して、バズワードの検出

…つまり、

  • 語彙ごとに複数の属性値が保存できる
  • 属性値で絞込み・ソート・グループ化ができたり、フックを用いてさまざまな操作を行ったりできる。

の2つの併せ技で出来ることが増えるというわけなのです。


夢が広がりまくりんぐですねー。

悩み深きAPI設計…

弊社SennaチームはAPIの設計に悩んでいるのです。
大体、こんなことで悩んでおります。

  • パフォーマンスが発揮できるように…
  • 実用的なように…
  • いろんな言語でバインディングを書きやすいように…
  • API仕様が安定するように…


というわけで、

  • このAPIじゃこういうアプリケーションが書きにくい
  • このAPIじゃこういう言語だとバインディングが書きにくい
  • そもそもこういう機能が欲しい

などというツッコミを大募集しております。
senna-devメーリングリストやブログなどで、
是非是非ツッコみまくってください!!!
高速で実用的で柔軟で安定した検索エンジンを目指してるんじゃい!!


というわけで、お待ちしぃ〜てぇ〜いまぁ〜すぅ〜 チャリラリラリラリラン(by 日本直販