[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に変換していろいろ試していこうかと思います。もしご興味があれば今後ともご参照ください。少しでもみなさまのお役に立てれば幸いです。

