Lucene.netで全ドキュメントを取得する

最近更新されたコンテンツのリストを取得する.

Lucene.netにはDocumentクラスのインスタンスを保存します.最近更新されたドキュメントを取得するなど,すべてのドキュメントを対象にした操作のメモです.

http://www.jguru.com/faq/view.jsp?EID=587213 に全てのドキュメント取得方法が議論されているように,全てのドキュメントに,固定値を設定したフィールドを1つ入れておいて,そのフィールド値で検索をかける,が正解です.

ダメな方法は,問い合わせ文に"a* b* ..."のような,ワイルドカードの問い合わせ文を書く方法.これは英文にしか通じない手ですし,ワイルドカードの処理は重くパフォーマンスは最悪でしょう.

固定値を設定したFieldがなくても,例えば整数で文書IDがあれば,文書IDが数字のDocumentを検索して取得すれば,全文書の取得ができます.

もしも適切なFieldがなくて,文書一覧取得が必要ならば,全ての文書のインデックス生成をやり直すのがいいでしょう.Lucene.netのDocumentクラスは,インスタンスごとに独立してFieldを設定できまる,つまり Key-Valueペア の集合として扱えますから,後からFieldを追加削除はできるのですが,いかんせん"すべての文書"を取得することがまずできなければ,先ほどのField追加ができないためです.

結局のところ,数字やDateなどで文書IDを設定しておく,これをルールにしておけば,困ることはなさそうです.

コード

実際にドキュメントを更新時間でソートして一覧取得するコードを書いてみます.
まず,ドキュメント作成時に,すべての文書を取り出すためのフィールドを1つ入れておきます.

 Document doc = new Document();            
 doc.Add(new Field("hogehoge", "hoehoe", Field.Store.NO, Field.Index.UN_TOKENIZED));

このField "hogehoge"に対してkeywordAnalyzer (UN_TOKENIZEDしたためか,StandardAnalyzerだと検索結果にひっかからない)を使い検索をかけます.

 Lucene.Net.Analysis.KeywordAnalyzer anl = new Lucene.Net.Analysis.KeywordAnalyzer();
 Lucene.Net.QueryParsers.QueryParser qpr = new Lucene.Net.QueryParsers.QueryParser(StorageFields.AllDocument, anl);
 Lucene.Net.Search.Sort sort = new Lucene.Net.Search.Sort(new Lucene.Net.Search.SortField("hogehoge", Lucene.Net.Search.SortField.AUTO, reverse));
 Search.Query q = qpr.Parse(StorageFields.AllDocument);
 _indexSearcher.Search(q, sort)); // _indexSearche は Search.IndexSearcher