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