2011-07-04 3 views
1

コンテキスト:
ヘルパーファサードクラスが自分のアプリケーションに検索メソッドを提供しています。 パフォーマンスは問題ではないため、クエリごとに新しいIndexSearcherが作成されます。クエリごとに Lucene 2.9.2:IndexSearcherのインスタンス化時にAlreadyClosedExceptionが発生する

は、新しい検索者は、このように作成されます。
File indexFile = new File(String absolutePathToIndex); 
IndexSearcher searcher = new IndexSearcher(indexFile.getAbsolutePath(), true); 

は、時々私は、検索対象のない共有はありませんので、私は理解していない AlreadyClosedExceptionを取得します。

アイデア?どのようにインデックスを開くためのベストプラクティス?既知の問題点? ありがとうございます。

スタックトレース:

org.apache.lucene.store.AlreadyClosedException: this Directory is closed 
     at org.apache.lucene.store.Directory.ensureOpen(Directory.java:251) 
     at org.apache.lucene.store.FSDirectory.listAll(FSDirectory.java:530) 
     at org.apache.lucene.index.SegmentInfos$FindSegmentsFile.run(SegmentInfos.java:585) 
     at org.apache.lucene.index.DirectoryReader.open(DirectoryReader.java:69) 
     at org.apache.lucene.index.IndexReader.open(IndexReader.java:476) 
     at org.apache.lucene.index.IndexReader.open(IndexReader.java:243) 
     at org.apache.lucene.search.IndexSearcher.<init>(IndexSearcher.java:78) 

提案された解決策#1:移動するための方法?

Directory directory = FSDirectory.open(File indexFile); 
IndexSearcher searcher = new IndexSearcher(directory, true); 
...do the query... 
searcher.close(); 

質問:溶液#1から上記のコードは、クエリごとに作成されます。ディレクトリも閉じる必要がありますか? Lucene 2.9.2のソースコードを確認したところ、searcher.close()readerオブジェクトに関連付けられたdirectoryを閉じません。

答えて

0

同時実行時にエラーが発生した場合は、複数のスレッドがディレクトリを閉じようとしているか、既に閉じられたディレクトリから読み込もうとしている可能性があります。 absolutePathがメソッド内のローカル変数であるか、複数のスレッドによって再利用されているオブジェクト内のインスタンス変数であるかを明確にしていないので、推測が困難です。

+0

を修正しました...なぜ複数のスレッドが同じオブジェクトをクローズしようとする必要がありますか?各スレッドはIndexSearcherの独自のインスタンスを取得します。 – basZero

1

この例では、呼び出す方法は廃止されました。だから、おそらくIndexSearcher(Directory path, boolean readOnly)の使用は、別の動作を示しています。

以降の検索が完了する前に、ディレクトリを閉じないようにする必要があります。たとえば、このディレクトリを複数回使用してSearcherを再インスタンス化すると、別のSearcherが破棄され、恐らくデストラクタのディレクトリが閉じられます。

したがって、すでに推奨されていないバージョンのctorを使用する場合は、Searcherごとに新しいDirectoryインスタンスを使用してみてください。

+0

IndexSearcherインスタンスの作成後、1つのクエリを実行して検索者を閉じます。 searcherオブジェクト自体は返されません。したがって、単一のクエリの後でこのオブジェクトに何も処理がないことが絶対に保証されます... – basZero

+0

私はsearcherオブジェクトを意味しません。最も重要なのは、非推奨のStringパスコンストラクターまたはDirectoryコンストラクターを使用する場合です。 – fyr

+0

Stringコンストラクタを使用しています。コード、2行目を参照してください。 – basZero

1

Luceneの新しいバージョンでは、SearcherManagerヘルパークラスを使用することをお勧めします。これにより、それ以外の方法で実装する必要のある並行性/ロックおよびライフサイクルのすべてのステップが隠されてしまいます。 Mike McCandlessから

基本的なチュートリアル、Luceneプロジェクトのコミッタ:http://blog.mikemccandless.com/2011/09/lucenes-searchermanager-simplifies.html

関連する問題