package com.robonobo.midas.search; import java.io.IOException; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.queryParser.QueryParser; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.search.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.robonobo.common.exceptions.SeekInnerCalmException; import com.robonobo.core.api.proto.CoreApi.SearchResponse; import com.robonobo.midas.model.MidasStream; import com.robonobo.midas.model.MidasStreamAttribute; @Service("searchService") public class SearchServiceImpl implements SearchService { // TODO: Put this in a config file somewhere public static final int MAX_SEARCH_RESULTS = 100; private QueryParser queryParser; @Autowired private SessionFactory sessionFactory; public SearchServiceImpl() { queryParser = new QueryParser("title", new StandardAnalyzer()); } /* (non-Javadoc) * @see com.robonobo.midas.search.SearchService#search(java.lang.String, java.lang.String, int) */ @Override public SearchResponse search(String searchType, String queryStr, int firstResult) throws IOException { if(!searchType.equals("stream")) throw new SeekInnerCalmException(); Session session = sessionFactory.getCurrentSession(); FullTextSession searchSession = Search.createFullTextSession(session); org.apache.lucene.search.Query luceneQuery; try { luceneQuery = queryParser.parse(buildLuceneQuery(queryStr)); } catch (ParseException e) { throw new IOException(e); } // Create hibernate search query FullTextQuery hibQuery = searchSession.createFullTextQuery(luceneQuery, MidasStream.class, MidasStreamAttribute.class); hibQuery.setMaxResults(MAX_SEARCH_RESULTS); hibQuery.setFirstResult(firstResult); // Make the response SearchResponse.Builder srb = SearchResponse.newBuilder(); srb.setFirstResult(firstResult); srb.setTotalResults(hibQuery.getResultSize()); for (Object resultObj : hibQuery.list()) { if(resultObj instanceof MidasStream) srb.addObjectId(((MidasStream)resultObj).getStreamId()); else srb.addObjectId(((MidasStreamAttribute)resultObj).getStream().getStreamId()); } return srb.build(); } private String buildLuceneQuery(String queryStr) { // The query here is for Streams or StreamAttributes, so we include the fields of both StringBuffer sb = new StringBuffer(); sb.append("title:\"").append(queryStr); sb.append("\" OR description:\"").append(queryStr); sb.append("\" OR value:\"").append(queryStr).append("\""); return sb.toString(); } }