| <HTML><!-- -*-java-*- --> |
| <!-- Lucene Search Demo via CompiledPageServlet --> |
| <!-- Copyright (c) 1998,2000 Douglass R. Cutting. --> |
| |
| <java type=import> |
| javax.servlet.* |
| javax.servlet.http.* |
| java.io.* |
| com.lucene.analysis.* |
| com.lucene.document.* |
| com.lucene.index.* |
| com.lucene.search.* |
| com.lucene.queryParser.* |
| demo.HTMLParser.Entities |
| </java> |
| |
| <java> |
| // get index from request |
| String indexName = request.getParameter("index"); |
| if (indexName == null) // default to "index" |
| indexName = "index"; |
| Searcher searcher = // make searcher |
| new IndexSearcher(getReader(indexName)); |
| |
| // get query from request |
| String queryString = request.getParameter("query"); |
| if (queryString == null) |
| throw new ServletException("no query specified"); |
| |
| int start = 0; // first hit to display |
| String startString = request.getParameter("start"); |
| if (startString != null) |
| start = Integer.parseInt(startString); |
| |
| int hitsPerPage = 10; // number of hits to display |
| String hitsString = request.getParameter("hitsPerPage"); |
| if (hitsString != null) |
| hitsPerPage = Integer.parseInt(hitsString); |
| |
| boolean showSummaries = true; // show summaries? |
| if ("false".equals(request.getParameter("showSummaries"))) |
| showSummaries = false; |
| |
| Query query = null; |
| try { // parse query |
| query = QueryParser.parse(queryString, "contents", analyzer); |
| } catch (ParseException e) { // error parsing query |
| </java> |
| <HEAD><TITLE>Error Parsing Query</TITLE></HEAD><BODY> |
| <p>While parsing `queryString`: `e.getMessage()` |
| <java> |
| return; |
| } |
| |
| String servletPath = request.getRequestURI(); // getServletPath should work |
| int j = servletPath.indexOf('?'); // here but doesn't, so we |
| if (j != -1) // remove query by hand... |
| servletPath = servletPath.substring(0, j); |
| |
| </java> |
| |
| <head><title>Lucene Search Results</title></head><body> |
| |
| <center> |
| <form name=search action=`servletPath` method=get> |
| <input name=query size=44 value='`queryString`'> |
| <input type=hidden name=index value="`indexName`"> |
| <input type=hidden name=hitsPerPage value=`hitsPerPage`> |
| <input type=hidden name=showSummaries value=`showSummaries`> |
| <input type=submit value=Search> |
| </form> |
| </center> |
| <java> |
| Hits hits = searcher.search(query); // perform query |
| int end = Math.min(hits.length(), start + hitsPerPage); |
| </java> |
| |
| <p>Hits <b><java type=print>start+1</java>-<java type=print>end</java></b> |
| (out of <java type=print>hits.length()</java> total matching documents): |
| |
| <ul> |
| <java> |
| for (int i = start; i < end; i++) { // display the hits |
| Document doc = hits.doc(i); |
| String title = doc.get("title"); |
| if (title.equals("")) // use url for docs w/o title |
| title = doc.get("url"); |
| </java> |
| <p><b><java type=print>(int)(hits.score(i) * 100.0f)</java>% |
| <a href="`doc.get("url")`"> |
| <java type=print>Entities.encode(title)</java> |
| </b></a> |
| <java> |
| if (showSummaries) { // maybe show summary |
| </java> |
| <ul><i>Summary</i>: |
| <java type=print>Entities.encode(doc.get("summary"))</java> |
| </ul> |
| <java> |
| } |
| } |
| </java> |
| </ul> |
| |
| <java> |
| if (end < hits.length()) { // insert next page button |
| </java> |
| <center> |
| <form name=search action=`servletPath` method=get> |
| <input type=hidden name=query value='`queryString`'> |
| <input type=hidden name=start value=`end`> |
| <input type=hidden name=index value="`indexName`"> |
| <input type=hidden name=hitsPerPage value=`hitsPerPage`> |
| <input type=hidden name=showSummaries value=`showSummaries`> |
| <input type=submit value=Next> |
| </form> |
| </center> |
| <java> |
| } |
| </java> |
| |
| </body> |
| |
| <java type=class> |
| |
| Analyzer analyzer = new StopAnalyzer(); // used to tokenize queries |
| |
| /** Keep a cache of open IndexReader's, so that an index does not have to |
| opened for each query. The cache re-opens an index when it has changed |
| so that additions and deletions are visible ASAP. */ |
| |
| static Hashtable indexCache = new Hashtable(); // name->CachedIndex |
| |
| class CachedIndex { // an entry in the cache |
| IndexReader reader; // an open reader |
| long modified; // reader's modified date |
| |
| CachedIndex(String name) throws IOException { |
| modified = IndexReader.lastModified(name); // get modified date |
| reader = IndexReader.open(name); // open reader |
| } |
| } |
| |
| IndexReader getReader(String name) throws ServletException { |
| CachedIndex index = // look in cache |
| (CachedIndex)indexCache.get(name); |
| |
| try { |
| if (index != null && // check up-to-date |
| (index.modified == IndexReader.lastModified(name))) |
| return index.reader; // cache hit |
| else { |
| index = new CachedIndex(name); // cache miss |
| } |
| } catch (IOException e) { |
| StringWriter writer = new StringWriter(); |
| PrintWriter pw = new PrintWriter(writer); |
| throw new ServletException("Could not open index " + name + ": " + |
| e.getClass().getName() + "--" + |
| e.getMessage()); |
| } |
| |
| indexCache.put(name, index); // add to cache |
| return index.reader; |
| } |
| </java> |