Creating the index in the local file system is not a solution for the particular situation as the index should be synchronized and shared by every node. One solution is clustering the JVM while using a Lucene RAMDirectory (keep in mind it disappears after a node failure) instead of a FSDirectory. Terracotta framework can be used to cluster the JVM. This blog entry shows a code snippet.
Anyway I thought not to go that far and decided to create the index in the database so that it can be shared by everyone. Lucence contains the JdbcDirectory interface for this purpose. However the implementation of this interface is not shipped with Lucene itself. I found a third party implementation of that. Compass project provides the implementation of JdbcDirectory. (No need to worry about compass configurations etc. JdbcDirectory can be used with pure Lucene without bothering about Compass Lucene stuff).
Here is a simple example
//you need to include lucene and jdbc jars import org.apache.lucene.store.jdbc.JdbcDirectory; import org.apache.lucene.store.jdbc.dialect.MySQLDialect; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;.
//code snippet to create index
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUser("root");
dataSource.setPassword("password");
dataSource.setDatabaseName("test");
dataSource.setEmulateLocators(true); //This is important because we are dealing with a blob type data field
JdbcDirectory jdbcDir = new JdbcDirectory(dataSource, new MySQLDialect(), "indexTable");
jdbcDir.create(); // creates the indexTable in the DB (test). No need to create it manually
.//code snippet for indexing
StandardAnalyzer analyzer = new StandardAnalyzer();
IndexWriter writer = new IndexWriter(jdbcDir, analyzer, true);
indexDocs(writer, dataSource.getConnection());
System.out.println("Optimizing...");
writer.optimize();
writer.close();
static void indexDocs(IndexWriter writer, Connection conn)
throws Exception {
String sql = "select id, name, color from pet";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
Document d = new Document();
d.add(new Field("id", rs.getString("id"), Field.Store.YES, Field.Index.NO));
d.add(new Field("name", rs.getString("name"), Field.Store.YES, Field.Index.TOKENIZED));
d.add(new Field("color", rs.getString("color"), Field.Store.YES, Field.Index.TOKENIZED));
writer.addDocument(d);
}
}
This is the indexing part. Searching part is same as the one in my previous post.