[PC] FlexLuceneでソート(その1)~Javaで記載されていたソートのサンプルをC#にしてみました~
FlexLuceneでソート
本家Luceneを使ったソートのサンプル(Java)を見つけました。さっそくC#にしてみました。
移植
基本的な構造部分は、簡単に置換で書き換えてしまいます。
変更前:import org.apache.lucene.
変更後:using FlexLucene.
その他、throuw Exceptionは、外してしまいました。Javaは、camelCaseなのに対して、C#は、PascalCaseなので、関数の名前とかも入れ替えました。
変更点
JavaとC#との差の他にLuceneのバージョンの違いなのか、サンプルは「Field.Store.YES」→C#は「FieldStore.YES」の違いがありました。これは、以前に遭遇していたのですんなり対応できました。
ソートの変更点
ソートに関わる部分は、インデックスを作る際にソートの対象となるFieldの追加するSortedDocValuesField()関数です。ソートに使う項目を指定し、値を保存しておきます。
doc.Add(new SortedDocValuesField(“date”, new BytesRef(date) ));
検索する際は、ソートの対象となる項目を指定するSort()関数と、Search()関数のパラメータ設定とが新しい設定項目です。Sort()関数は、複数の項目を指定することができるようです。下の例は、第一優先として”date”の項目でソートし、次にScoreでソートするようです。Search()の第3引数は、上記のSort()で作成したsortを代入するのと、第4引数は、Scoreを使うかどうか、第5引数は、maxScoreを得るか否かの指定だそうです。パフォーマンスを気にする場合は、maxScoreは、falseにすることを推奨しています。私は、サンプルそのままにtrueにしています。
Sort sort = new Sort(new SortField(“date”, SortFieldType.STRING, true), SortField.FIELD_SCORE);
TopDocs docs = idxSearcher.Search(query, 10, sort, true, true);
using System; using FlexLucene.Analysis; using FlexLucene.Analysis.Standard; using FlexLucene.Document; using FlexLucene.Index; using FlexLucene.Search; using FlexLucene.Store; using FlexLucene.Util; using java.io; namespace TestSort { class Program { public static Analyzer analyzer = new StandardAnalyzer(); public static IndexWriterConfig config = new IndexWriterConfig(analyzer); public static RAMDirectory ramDirectory = new RAMDirectory(); public static IndexWriter indexWriter; static void Main(string[] args) { CreateIndex(); SearchSingleTerm("title", "lucene"); ramDirectory.Close(); } public static void createDoc(String author, String title, String date) { Document doc = new Document(); doc.Add(new TextField("author", author, FieldStore.YES)); doc.Add(new TextField("title", title, FieldStore.YES)); //doc.add(new Field ("date", date, Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.Add(new SortedDocValuesField("date", new BytesRef(date) )); doc.Add(new StoredField("date", date)); indexWriter.AddDocument(doc); } public static void CreateIndex() { try { indexWriter = new IndexWriter(ramDirectory, config); createDoc("Sam", "Lucece index option analyzed vs not analyzed", "2016-12-12 20:19:57"); createDoc("Sam", "Lucene field boost and query time boost example", "2016-03-16 16:57:44"); createDoc("Jack", "How to do Lucene search highlight example", "2016-03-16 17:47:38"); createDoc("Smith", "Lucene BooleanQuery is depreacted as of 5.3.0", "2015-04-30 11:44:25"); createDoc("Smith", "What is term vector in Lucene", "2015-04-10 20:33:53"); indexWriter.Close(); } catch (IOException ex) { System.Console.WriteLine("Exception : " + ex.getLocalizedMessage()); } } public static void SearchIndexNoSortAndDisplayResults(Query query) { try { IndexReader idxReader = DirectoryReader.Open(ramDirectory); IndexSearcher idxSearcher = new IndexSearcher(idxReader); TopDocs docs = idxSearcher.Search(query, 10); System.Console.WriteLine("length of top docs: " + docs.ScoreDocs.Length); foreach (ScoreDoc doc in docs.ScoreDocs) { Document thisDoc = idxSearcher.Doc(doc.Doc); System.Console.WriteLine(doc.Doc + "\t" + thisDoc.Get("author") + "\t" + thisDoc.Get("title")); } } catch (IOException e) { e.printStackTrace(); } finally { } } public static void SearchIndexAndDisplayResults(Query query) { try { IndexReader idxReader = DirectoryReader.Open(ramDirectory); IndexSearcher idxSearcher = new IndexSearcher(idxReader); Sort sort = new Sort(new SortField("date", SortFieldType.STRING, true), SortField.FIELD_SCORE); TopDocs docs = idxSearcher.Search(query, 10, sort, true, true); System.Console.WriteLine("length of top docs: " + docs.ScoreDocs.Length + " sort by: " + sort); foreach (ScoreDoc doc in docs.ScoreDocs) { Document thisDoc = idxSearcher.Doc(doc.Doc); System.Console.WriteLine(doc.Doc + "\t" + thisDoc.Get("author") + "\t" + thisDoc.Get("title") + "\t" + thisDoc.Get("date")); } } catch (IOException e) { e.printStackTrace(); } finally { } } public static void SearchSingleTerm(String field, String termText) { Term term = new Term(field, termText); TermQuery termQuery = new TermQuery(term); SearchIndexAndDisplayResults(termQuery); SearchIndexNoSortAndDisplayResults(termQuery); } } }
以上のコードでコンパイルと動作確認を実施しました。Visual Studioをお使いの人は是非お試しください。
まとめ
Lucene 5.3を使ったサンプルサイトを見つけました。Luceneのバージョン2.9を使っていた私にとって新しいことがいろいろ書いてあるので、これをFlexLuceneに変換していろいろ試していこうかと思います。もしご興味があれば今後ともご参照ください。少しでもみなさまのお役に立てれば幸いです。