Skip to content

June 1, 2011

1

Configure Lucene IndexWriter and IndexSearcher in Spring applicationContext.xml

Problem: you want to define Lucene IndexWriter and IndexSearcher as beans inside your Spring application to be injected/autowired into other beans.

Solution: follow the following steps.

  • define the Lucene version as a constant
  • define a Lucene analyzer (StandardAnalyzer) as a bean
  • define a Lucene directory as a bean, using a factory-method for instantiation
  • define an IndexWriter, wiring in the Lucene directory and an IndexWriterConfig set to use your previously-defined analyzer
  • define an IndexSearcher, wiring in the Lucene directory
  • define also a query parser (StandardQueryParser), wiring in the analyzer bean

You can then wire/autowire these beans into your application beans, for example:

@Autowired
private IndexWriter indexWriter;

Here is the resulting XML config after following the above steps, which you will place in your Spring applicationContext.xml:

<!-- LUCENE SEARCH CONFIG -->
<!-- set the Lucene version -->
<util:constant id="LUCENE_VERSION" static-field="org.apache.lucene.util.Version.LUCENE_31" />
<!-- set your analyzer, to be used by the IndexWriter and QueryParser -->
<bean id="luceneAnalyzer" class="org.apache.lucene.analysis.standard.StandardAnalyzer">
  <constructor-arg ref="LUCENE_VERSION"/>
</bean>
<!-- set your Lucene directory -->
<!-- in this case I am pulling the location from a properties file -->
<!-- also, using the SimpleFSLockFactory -->
<bean id="luceneDirectory" class="org.apache.lucene.store.FSDirectory" factory-method="open">
  <constructor-arg>
    <bean class="java.io.File">
      <constructor-arg value="${config.search.indexDir}" />
    </bean>
  </constructor-arg>
  <constructor-arg>
    <bean class="org.apache.lucene.store.SimpleFSLockFactory" />
  </constructor-arg>
</bean>
<!-- now you're ready to define the IndexWriter -->
<bean id="indexWriter" class="org.apache.lucene.index.IndexWriter">
  <constructor-arg ref="luceneDirectory" />
  <constructor-arg>
    <bean class="org.apache.lucene.index.IndexWriterConfig">
      <constructor-arg ref="LUCENE_VERSION"/>
      <constructor-arg ref="luceneAnalyzer" />
    </bean>
  </constructor-arg>
</bean>

<!-- define the IndexSearcher -->
<bean id="indexSearcher" class="org.apache.lucene.search.IndexSearcher" depends-on="indexWriter">
  <constructor-arg ref="luceneDirectory" />
</bean>
<!-- also useful is to define a query parser -->
<bean id="queryParser" class="org.apache.lucene.queryParser.standard.StandardQueryParser">
  <constructor-arg ref="luceneAnalyzer" />
</bean>

Now you’re ready to rock and roll with Lucene in your application. There is one problem, however. On first execution, instantiation of the IndexSearcher will fail because no index exists yet. I have not found an elegant solution to this problem, so what I do is simply comment out the IndexSearcher bean definition on first run. Doing so necessitates this bean be optional in your application. So, where I autowire IndexWriter, I set required=false:

@Autowired(required=false)
private IndexSearcher indexSearcher;

Once a Lucene index exists, I uncomment the searcher bean. If there is a better way to solve this problem, please share a comment!

Read more from Java
1 Comment Post a comment
  1. Aug 12 2011

    To create initial indexes;

    1. Define a utility bean which will be instantiated before IndexSearcher

    i.e.

    2. At the constructor method of the LuceneUtility class load / create initial indexes from
    either database or any other source .

    Best,

    Reply

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments