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