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