Using Lucene Directory/IndexReader direct w/o DB Session

#1

Hey!
We are currently using Hibernate Search 5.11.0 and trying to implement some kind of autocompleter for search requests.

To do that we are currently just opening the Lucene index directly with:

Directory dir = FSDirectory.open(...);
Reader reader = DirectoryReader.open(dir);
IndexSearcher searcher = new IndexSearcher(reader);

Later on we check sometimes if the reader needs to access the new version of the index (openIfChanged).

This works fine and we also think, that this works in parallel with the Hibernate Search write access to the index. (automatic indexing is on)

But we are not sure if this should work or is intended to be possible. Hibernate and our code run in the same vm. Only Hibernate has write access to the index but the index is still opened multiple times, which should not be possible?
Or does the the config exclusiv_index_use indent something else we are currently not aware of?

Can we maybe get access to the Hibernate Lucene Directory / IndexReader object? Here it is important to not open a connection to the database. Otherwise the feature just uses to much resources in our scenario.

Best regards
Marco

0 Likes

#2

Hi,

I think you’re looking for searchFactory.getIndexReaderAccessor(): https://docs.jboss.org/hibernate/search/5.11/reference/en-US/html_single/#IndexReaders

If you follow the recommendations from the documentation, exclusive_index_use is not necessary: everything will work fine: Lucene handles the concurrent accesses.

At the moment, your only way to get access to the search factory without creating a session would be to rely on the SearchIntegratorHelper SPI: call either SearchIntegratorHelper.extractFromSessionFactory or SearchIntegratorHelper.extractFromEntityManagerFactory.

You should en up with something like this:

@PersistenceUnit
private EntityManagerFactory emFactory;

public List<Something> search(String terms) {
    SearchFactory searchFactory = SearchIntegratorHelper.extractFromEntityManagerFactory(emFactory);
    IndexReader reader = searchFactory.getIndexReaderAccessor().open(MyEntity.class);
    try {
        //perform read-only operations on the reader
        return result;
    }
    finally {
        // You MUST NOT call close() directly on the reader. Use this instead.
        searchFactory.getIndexReaderAccessor().close(reader);
    }
}
0 Likes

#3

Thank you yrodiere!

The SearchIntegrationHelper was the interface we are looking for.

0 Likes