1
22
23 package com.liferay.portal.search.lucene;
24
25 import com.liferay.portal.kernel.search.Document;
26 import com.liferay.portal.kernel.search.DocumentImpl;
27 import com.liferay.portal.kernel.search.Field;
28 import com.liferay.portal.kernel.search.Hits;
29 import com.liferay.portal.kernel.search.HitsImpl;
30 import com.liferay.portal.kernel.search.IndexSearcher;
31 import com.liferay.portal.kernel.search.SearchEngineUtil;
32 import com.liferay.portal.kernel.search.SearchException;
33 import com.liferay.portal.kernel.search.Sort;
34 import com.liferay.portal.kernel.util.GetterUtil;
35 import com.liferay.portal.kernel.util.StringPool;
36 import com.liferay.portal.kernel.util.Time;
37
38 import java.io.IOException;
39
40 import java.util.List;
41
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44 import org.apache.lucene.queryParser.ParseException;
45 import org.apache.lucene.queryParser.QueryParser;
46 import org.apache.lucene.search.BooleanQuery;
47 import org.apache.lucene.search.SortField;
48
49
55 public class LuceneIndexSearcherImpl implements IndexSearcher {
56
57 public Hits search(long companyId, String query, int start, int end)
58 throws SearchException {
59
60 Sort sort = null;
61
62 return search(companyId, query, sort, start, end);
63 }
64
65 public Hits search(
66 long companyId, String query, Sort sort, int start, int end)
67 throws SearchException {
68
69 Hits hits = null;
70
71 org.apache.lucene.search.IndexSearcher searcher = null;
72
73 try {
74 searcher = LuceneUtil.getSearcher(companyId);
75
76 org.apache.lucene.search.Sort luceneSort = null;
77
78 if (sort != null) {
79 luceneSort = new org.apache.lucene.search.Sort(
80 new SortField(sort.getFieldName(), sort.isReverse()));
81 }
82
83 QueryParser parser = new QueryParser(
84 StringPool.BLANK, LuceneUtil.getAnalyzer());
85
86 org.apache.lucene.search.Hits luceneHits =
87 searcher.search(parser.parse(query), luceneSort);
88
89 hits = subset(luceneHits, start, end);
90 }
91 catch (RuntimeException re) {
92
93
96 String msg = GetterUtil.getString(re.getMessage());
97
98 if (!msg.endsWith("does not appear to be indexed")) {
99 throw re;
100 }
101 }
102 catch (Exception e) {
103 if (e instanceof BooleanQuery.TooManyClauses ||
104 e instanceof ParseException) {
105
106 _log.error("Parsing keywords " + query, e);
107
108 return new HitsImpl();
109 }
110 else {
111 throw new SearchException(e);
112 }
113 }
114 finally {
115 try {
116 if (searcher != null) {
117 searcher.close();
118 }
119 }
120 catch (IOException ioe) {
121 throw new SearchException(ioe);
122 }
123 }
124
125 return hits;
126 }
127
128 protected DocumentImpl getDocument(
129 org.apache.lucene.document.Document oldDoc) {
130
131 DocumentImpl newDoc = new DocumentImpl();
132
133 List<org.apache.lucene.document.Field> oldFields = oldDoc.getFields();
134
135 for (org.apache.lucene.document.Field oldField : oldFields) {
136 String[] values = oldDoc.getValues(oldField.name());
137
138 if ((values != null) && (values.length > 1)) {
139 Field newField = new Field(
140 oldField.name(), values, oldField.isTokenized());
141
142 newDoc.add(newField);
143 }
144 else {
145 Field newField = new Field(
146 oldField.name(), oldField.stringValue(),
147 oldField.isTokenized());
148
149 newDoc.add(newField);
150 }
151 }
152
153 return newDoc;
154 }
155
156 protected Hits subset(
157 org.apache.lucene.search.Hits luceneHits, int start, int end)
158 throws IOException {
159
160 int length = luceneHits.length();
161
162 if ((start == SearchEngineUtil.ALL_POS) &&
163 (end == SearchEngineUtil.ALL_POS)) {
164
165 start = 0;
166 end = length;
167 }
168
169 long startTime = System.currentTimeMillis();
170
171 Hits subset = new HitsImpl();
172
173 if ((start > - 1) && (start <= end)) {
174 if (end > length) {
175 end = length;
176 }
177
178 int subsetTotal = end - start;
179
180 Document[] subsetDocs = new DocumentImpl[subsetTotal];
181 float[] subsetScores = new float[subsetTotal];
182
183 int j = 0;
184
185 for (int i = start; i < end; i++, j++) {
186 subsetDocs[j] = getDocument(luceneHits.doc(i));
187 subsetScores[j] = luceneHits.score(i);
188 }
189
190 subset.setLength(length);
191 subset.setDocs(subsetDocs);
192 subset.setScores(subsetScores);
193 subset.setStart(startTime);
194
195 float searchTime =
196 (float)(System.currentTimeMillis() - startTime) / Time.SECOND;
197
198 subset.setSearchTime(searchTime);
199 }
200
201 return subset;
202 }
203
204 private static Log _log = LogFactory.getLog(LuceneIndexSearcherImpl.class);
205
206 }