1
22
23 package com.liferay.portal.search.lucene;
24
25 import com.liferay.portal.kernel.dao.orm.QueryUtil;
26 import com.liferay.portal.kernel.search.Document;
27 import com.liferay.portal.kernel.search.DocumentImpl;
28 import com.liferay.portal.kernel.search.Field;
29 import com.liferay.portal.kernel.search.Hits;
30 import com.liferay.portal.kernel.search.HitsImpl;
31 import com.liferay.portal.kernel.search.IndexSearcher;
32 import com.liferay.portal.kernel.search.Query;
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[] sorts, 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 (sorts != null) {
80 SortField[] sortFields = new SortField[sorts.length];
81
82 for (int i = 0; i < sorts.length; i++) {
83 Sort sort = sorts[i];
84
85 sortFields[i] = new SortField(
86 sort.getFieldName(), sort.getType(), sort.isReverse());
87 }
88
89 luceneSort = new org.apache.lucene.search.Sort(sortFields);
90 }
91
92 org.apache.lucene.search.Hits luceneHits = searcher.search(
93 QueryTranslator.translate(query), luceneSort);
94
95 hits = subset(luceneHits, start, end);
96 }
97 catch (RuntimeException re) {
98
99
102 String msg = GetterUtil.getString(re.getMessage());
103
104 if (!msg.endsWith("does not appear to be indexed")) {
105 throw re;
106 }
107 }
108 catch (Exception e) {
109 if (e instanceof BooleanQuery.TooManyClauses ||
110 e instanceof ParseException) {
111
112 _log.error("Query: " + query, e);
113
114 return new HitsImpl();
115 }
116 else {
117 throw new SearchException(e);
118 }
119 }
120 finally {
121 try {
122 if (searcher != null) {
123 searcher.close();
124 }
125 }
126 catch (IOException ioe) {
127 throw new SearchException(ioe);
128 }
129 }
130
131 return hits;
132 }
133
134 protected DocumentImpl getDocument(
135 org.apache.lucene.document.Document oldDoc) {
136
137 DocumentImpl newDoc = new DocumentImpl();
138
139 List<org.apache.lucene.document.Field> oldFields = oldDoc.getFields();
140
141 for (org.apache.lucene.document.Field oldField : oldFields) {
142 String[] values = oldDoc.getValues(oldField.name());
143
144 if ((values != null) && (values.length > 1)) {
145 Field newField = new Field(
146 oldField.name(), values, oldField.isTokenized());
147
148 newDoc.add(newField);
149 }
150 else {
151 Field newField = new Field(
152 oldField.name(), oldField.stringValue(),
153 oldField.isTokenized());
154
155 newDoc.add(newField);
156 }
157 }
158
159 return newDoc;
160 }
161
162 protected Hits subset(
163 org.apache.lucene.search.Hits luceneHits, int start, int end)
164 throws IOException {
165
166 int length = luceneHits.length();
167
168 if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS)) {
169 start = 0;
170 end = length;
171 }
172
173 long startTime = System.currentTimeMillis();
174
175 Hits subset = new HitsImpl();
176
177 if ((start > - 1) && (start <= end)) {
178 if (end > length) {
179 end = length;
180 }
181
182 int subsetTotal = end - start;
183
184 Document[] subsetDocs = new DocumentImpl[subsetTotal];
185 float[] subsetScores = new float[subsetTotal];
186
187 int j = 0;
188
189 for (int i = start; i < end; i++, j++) {
190 subsetDocs[j] = getDocument(luceneHits.doc(i));
191 subsetScores[j] = luceneHits.score(i);
192 }
193
194 subset.setLength(length);
195 subset.setDocs(subsetDocs);
196 subset.setScores(subsetScores);
197 subset.setStart(startTime);
198
199 float searchTime =
200 (float)(System.currentTimeMillis() - startTime) / Time.SECOND;
201
202 subset.setSearchTime(searchTime);
203 }
204
205 return subset;
206 }
207
208 private static Log _log = LogFactory.getLog(LuceneIndexSearcherImpl.class);
209
210 }