JavaとLuceneは初めてです。コードはファイルから行を取得してLuceneインデックスに格納します。しかし、インデックスから検索して読み取るためにIndexReader
を作成すると例外をスローします。
私のJavaコードは以下のとおりです。IndexReader
を作成すると、IndexNotFoundException
がスローされます。
static String itemsfreq[];
static StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
static IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_35, analyzer);
public static void index_data(Directory indexed_document,int doc_num,IndexWriter w) throws IOException
{
for(int i = 0;i < itemsfreq.length;i++)
{
Document doc = new Document();
doc.add(new Field(Integer.toString(doc_num)+","+itemsfreq[i],itemsfreq[i++], Field.Store.YES, Field.Index.ANALYZED));
w.addDocument(doc);
}
}
//Gets string from a file and insert it in INDEX named indexed_document
public static void main(String[] args) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader("fullText100.txt"));
String line;
int i = 0;
Directory indexed_document = new RAMDirectory();
IndexWriter writer = new IndexWriter(indexed_document, config);
while((line=reader.readLine()) != null)
{
if(i == 1)
{
break;
}
itemsfreq = line.split(" ");
index_data(indexed_document,i,writer);
i++;
}
IndexReader r = IndexReader.open(indexed_document);
}
リーダーを使用してインデックスを開く前に、一度writer.commit()
を呼び出します。
インデックスに変更を書き込むには、インデックスライターを閉じてから、IndexReaderを開く必要があります。
writer.close();
書き込みが完了する前にIndexReaderを開く必要がある場合は、変更を確認するためにIndexReaderにインデックスを再度開くように指示する必要があります。
IndexSearcherを開く前に、明示的にcommitを呼び出す必要があります。
directory = new RAMDirectory();
iwriter = new IndexWriter(directory, config);
iwriter.commit();
サーチャーを開く
ireader = DirectoryReader.open(directory);
isearcher = new IndexSearcher(ireader);
また、ドキュメントを追加した後にcommitを呼び出す必要があることを忘れないでください。そうしないと、検索で見つからない場合があります。サーチャーはコミット後に再度開く必要があります(もちろん古いサーチャーを閉じます)。
iwriter.commit();
ファイルシステムに適切なディレクトリを作成し、メモリにFSDirectory
を作成してインデックスを作成したが、実際にはまだドキュメントを追加していないため、このエラーが発生しました(Lucene.Net、C#)。
具体的には、新しいドキュメントを追加するコードは、リーダーで重複を追加していないことを確認していましたが、セグメントがまだないため、最初のドキュメントを追加しようとすると例外がスローされました。
私はこれを次のように扱いました:
// Make a reader to check the index for duplicates
// The reader will only be aware of items that were in the index before it was created
IndexReader reader = null;
try {
reader = IndexReader.Open( index, true );
} catch( IOException ) {
// There is no segments file because the index is empty
reader = null;
}
... // inside a method called by that scope, with reader passed in
// See if it exists already
// If the reader is null, then the index is empty
if( reader != null ) {
var existsTerm = new Term( SingleFieldIndexManager.FieldName, formattedTerm );
var matches = reader.TermDocs( existsTerm );
if( matches.Next() ) {
// It's already in there, no need to add again
return;
}
}
... // back to the first method after a return
// dispose of the reader if we managed to create one
if( reader != null ) {
reader.Dispose();
}