Lucene.LINQのソースをざっと読んで,できることをまとめてみる

Lucene.LinqAPIとコードをざっと読みました.思いつくままに流してみます.

データベースとの連携動作とインデックス付加

まず,SQLデータベースのインデックス化が可能です.インデックスファイルは,プログラムが動いているマシンのメモリまたはローカルファイルシステムに作成できます.

やり方は,まずSQLデータベースを接続するために,System.Data.Linq.DataContext を継承するDateContextクラスを作ります.インデックスとの結合は,Lucene.Linq.DatabaseIndexSet<先ほどのdataContextクラス>を継承するクラスを定義すれば完了です.SQLデータベースのテーブルがクラスに,テーブルのRowがインスタンスに,テーブルのColomnがクラスのフィールドにそれぞれ対応します.Luceneのインデックスオプションは,クラスおよびフィールドの属性で指定します.

またSQLデータベースを使わず,インスタンスの保存/検索ができます.こちらは,先ほどのSQLデータベースとの接続の設定がないだけで,やり方は同じです.

データファイルはクラスの型ごとに作られる

型に1つづつインデックスファイルがあります.例えばCustomerというクラスをインデックスに登録すると,Customerというフォルダの下にLucene.netのインデックスファイルが作られます.インデックスフォルダの下に,型名でフォルダを作り,その下にインデックスファイルを作ります.

マルチスレッド対応

Lucene.Netのインデックスへの読み書き処理には,しっかり排他制御が入れてあり,マルチスレッドに対応したコードになっています.

検索結果の取得

LINQを通して,検索結果が得られます(ヒット結果は,クラスに実装した Lucene.Linq.IHit インタフェースのプロパティに設定される).またPagedList.csで定義されるSystem.Collections.Generic 名前空間のPagedListによる,ページ単位での検索結果取得も可能らしい(実行コード試していないので,らしい,としかいえない)です.

インタフェースはインデックスに追加できない

インタフェースでValueObjectを定義して,実装は別にクラスを用意することがあります.Lucene.Linq.MappingのDocument属性はクラスにのみ設定できます.このためインタフェースをインデックス可能にはできません.

実装しているLINQの操作は

Where, Select, Group, Count, Skip, Take, ElementAt, First,そして Lastの9つです.これ以外,例えば FirstOrDefaultなど,はサポートしておらず,それらの操作をしたときには NotSupportedException が発生します.(QueryBinder.cs 71行目あたりを参照)
またFirstで要素を取得しようとして,インデックスに該当する要素が1つもない場合は,例外 IndexOutOfRange が発生します.FirstOrDefaultと同等のことをするには,検索式のHitの有無をプロパティ Count で確認してから,要素があるならばFirstで取得すればよいでしょう.

未調査

フィールドに配列が使えるかどうか.Lucene.netのDocumentは同じ名前のFieldを複数追加できますから,配列が使える構造ではあるはずです.SQLとの連携を考えると,プリミティブ型の配列だけに限定したほうがいいでしょうが.

インスタンスの永続性とデータベース

ソースファイルと一緒にあるTODOファイルを見ると,db4objectsと同じようなクラスのフィールド情報をそのまま利用した検索を入れたいと書いてありました.

Lucene.Linqがやっているのは,LINQ検索式の実装とそれに必要なLucene.netのドキュメントとインスタンスの相互の変換ですから,つまりは,Lucene.netにオブジェクトデータベースを被せているのと同じことなのだと思います.

完成形のイメージは,db4objectsがLucene.netと結合したものとなるのではないでしょうか.また,C#というかIL直接実行可能なOSを組む人がいたら,db4objects+Lucene.netのイメージファイルは,そのままファイルシステム相当のレイヤになりますから,かなり基礎的でもあり,使う範囲が広いものだと思います.