1 25 26 package org.nemesis.forum.search; 27 28 import java.io.File ; 29 import java.util.Date ; 30 import java.util.Iterator ; 31 32 import org.apache.commons.logging.Log; 33 import org.apache.commons.logging.LogFactory; 34 import org.apache.lucene.analysis.Analyzer; 35 import org.apache.lucene.analysis.standard.StandardAnalyzer; 36 import org.apache.lucene.document.Document; 37 import org.apache.lucene.index.IndexReader; 38 import org.apache.lucene.queryParser.QueryParser; 39 import org.apache.lucene.search.BooleanQuery; 40 import org.apache.lucene.search.DateFilter; 41 import org.apache.lucene.search.Hits; 42 import org.apache.lucene.search.IndexSearcher; 43 import org.apache.lucene.search.Query; 44 import org.nemesis.forum.Forum; 45 import org.nemesis.forum.ForumThread; 46 import org.nemesis.forum.User; 47 import org.nemesis.forum.config.ConfigLoader; 48 49 52 public class Searcher { 53 static protected Log log = LogFactory.getLog(Searcher.class); 54 55 private static Analyzer analyzer = new StandardAnalyzer(); 56 private static final int MAX_RESULTS_SIZE = 500; 57 58 private int[] results = null; 59 60 private String queryString = ""; 61 private Date beforeDate = null; 62 private Date afterDate = null; 63 private User user = null; 64 private ForumThread thread = null; 65 66 private Forum forum = null; 67 68 public Searcher(Forum forum) { 69 this.forum = forum; 70 } 71 72 public void setQueryString(String queryString) { 73 this.queryString = queryString; 74 results = null; 75 } 76 77 public String getQueryString() { 78 return queryString; 79 } 80 81 public void setBeforeDate(Date beforeDate) { 82 this.beforeDate = beforeDate; 83 results = null; 84 } 85 86 public Date getBeforeDate() { 87 return beforeDate; 88 } 89 90 public void setAfterDate(Date afterDate) { 91 this.afterDate = afterDate; 92 results = null; 93 } 94 95 public Date getAfterDate() { 96 return afterDate; 97 } 98 99 public User getFilteredUser() { 100 return user; 101 } 102 103 public void filterOnUser(User user) { 104 this.user = user; 105 results = null; 106 } 107 108 public ForumThread getFilteredThread() { 109 return thread; 110 } 111 112 public void filterOnThread(ForumThread thread) { 113 this.thread = thread; 114 results = null; 115 } 116 117 public int resultCount() { 118 if (results == null) { 119 executeQuery(); 120 } 121 return results.length; 122 } 123 124 public Iterator results() { 125 if (results == null) { 126 executeQuery(); 127 } 128 return new QueryIterator(forum,results); 129 } 130 131 public Iterator results(int startIndex, int numResults) { 132 if (results == null) { 133 executeQuery(); 134 } 135 return new QueryIterator( forum,results, startIndex, numResults); 136 } 137 138 private void executeQuery() { 139 IndexReader reader = null; 140 try { 141 reader = IndexReader.open(new File (ConfigLoader.getInstance().getConfig().getDataDir(), "index")); 142 IndexSearcher searcher = new IndexSearcher(reader); 143 144 Query bodyQuery = QueryParser.parse(queryString, "body", analyzer); 145 Query subjectQuery = QueryParser.parse(queryString, "subject", analyzer); 146 String forumID = Integer.toString(forum.getID()); 147 BooleanQuery comboQuery = new BooleanQuery(); 148 comboQuery.add(subjectQuery, false, false); 149 comboQuery.add(bodyQuery, false, false); 150 151 MultiFilter multiFilter = new MultiFilter(3); 152 153 multiFilter.add(new FieldFilter("forumID", forumID)); 155 156 if (beforeDate != null || afterDate != null) { 158 if (beforeDate != null && afterDate != null) { 159 multiFilter.add(new DateFilter("creationDate", beforeDate, afterDate)); 160 } else if (beforeDate == null) { 161 multiFilter.add(DateFilter.After("creationDate", afterDate)); 162 } else { 163 multiFilter.add(DateFilter.Before("creationDate", beforeDate)); 164 } 165 } 166 167 if (user != null) { 169 String userID = Integer.toString(user.getID()); 170 multiFilter.add(new FieldFilter("userID", userID)); 171 } 172 173 if (thread != null) { 175 String threadID = Integer.toString(thread.getID()); 176 multiFilter.add(new FieldFilter("threadID", threadID)); 177 } 178 179 Hits hits = searcher.search(comboQuery, multiFilter); 180 int numResults = hits.length() < MAX_RESULTS_SIZE ? hits.length() : MAX_RESULTS_SIZE; 182 int[] messages = new int[numResults]; 183 for (int i = 0; i < numResults; i++) { 184 messages[i] = Integer.parseInt(((Document) hits.doc(i)).get("messageID")); 185 } 186 results = messages; 187 188 } catch (Throwable e) { 189 log.error("", e); 190 results = new int[0]; 191 } finally { 192 try { 193 reader.close(); 194 } catch (Exception e) { 195 } 196 197 } 198 } 199 200 } 201 | Popular Tags |