Friday, May 7, 2010

Remote Katta client example

I couldn't find too much information on running external Katta clients so here's an example of how I ended up getting it to work:
import net.sf.katta.lib.lucene.Hit;
import net.sf.katta.lib.lucene.Hits;
import net.sf.katta.lib.lucene.ILuceneClient;

import org.apache.hadoop.io.MapWritable;
import org.apache.hadoop.io.Text;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Version;

import com.google.inject.Inject;
import com.google.inject.internal.Lists;

public class SomeSearchKattaImpl implements SomeSearch {

 private final Analyzer analyzer;
 private final ILuceneClient client;
 private final List indexedFields;
 private static final String[] indexName = {"field"}; 
 
 @Inject
 protected SomeSearchKattaImpl(Logger logger, StandardAnalyzer analyzer,
   ILuceneClient client) {
  this.logger = logger;
  this.client = client;
  this.analyzer = analyzer;
  
  indexedFields = Lists.newArrayList();
  indexedFields.add(Field1);
  indexedFields.add(Field2);
  this.logger.fine(getClass().getName() + " loaded...");
 }
 
 private Query getQuery(String query) throws ParseException {  
  MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30,
    (String[])indexedFields.toArray(new String[0]), analyzer);
  return parser.parse(query);
 }
 
 @Override
 public List getResults(
   String query, int start, int count) throws Exception {
  Query q = getQuery(query);
  Hits hits = client.search(q, indexName, start + count);
  List window = hits.getHits().subList(start, 
    (hits.getHits().size() < start + count) ? hits.getHits().size() : start + count);
  List results = Lists.newArrayList();
  //TODO: Should we limit this by field?
  for (MapWritable writable: client.getDetails(window)) {
   ResultLite result = new ResultLite();

   result.setSomething(writable.get(new Text("title")).toString());
   results.add(result);
  }
  return results;
 }
}

and I injected the LuceneClient like this:
@Provides 
public ILuceneClient getLuceneClient() {  
 ZkConfiguration config = 
  new ZkConfiguration("/katta/katta.zk.properties");
        
 ILuceneClient client = new LuceneClient(config);
 return client;
}