001
014
015 package com.liferay.portal.kernel.search;
016
017 import com.liferay.portal.kernel.search.facet.Facet;
018 import com.liferay.portal.kernel.search.filter.BooleanFilter;
019 import com.liferay.portal.kernel.search.filter.Filter;
020 import com.liferay.portal.kernel.search.filter.TermsFilter;
021 import com.liferay.portal.kernel.search.generic.BooleanQueryImpl;
022 import com.liferay.portal.kernel.search.generic.MatchAllQuery;
023 import com.liferay.portal.kernel.util.ArrayUtil;
024 import com.liferay.portal.kernel.util.GetterUtil;
025 import com.liferay.portal.kernel.util.ListUtil;
026 import com.liferay.portal.kernel.util.SetUtil;
027 import com.liferay.portal.kernel.util.UnicodeProperties;
028 import com.liferay.portal.kernel.util.Validator;
029 import com.liferay.portal.model.Group;
030 import com.liferay.portal.service.GroupLocalServiceUtil;
031 import com.liferay.portlet.expando.model.ExpandoBridge;
032 import com.liferay.portlet.expando.model.ExpandoColumnConstants;
033 import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
034
035 import java.util.List;
036 import java.util.Map;
037 import java.util.Set;
038
039
042 public class FacetedSearcher extends BaseSearcher {
043
044 public static Indexer<?> getInstance() {
045 return new FacetedSearcher();
046 }
047
048 protected void addSearchExpandoKeywords(
049 BooleanQuery searchQuery, SearchContext searchContext,
050 String keywords, String className)
051 throws Exception {
052
053 ExpandoBridge expandoBridge = ExpandoBridgeFactoryUtil.getExpandoBridge(
054 searchContext.getCompanyId(), className);
055
056 Set<String> attributeNames = SetUtil.fromEnumeration(
057 expandoBridge.getAttributeNames());
058
059 for (String attributeName : attributeNames) {
060 UnicodeProperties properties = expandoBridge.getAttributeProperties(
061 attributeName);
062
063 int indexType = GetterUtil.getInteger(
064 properties.getProperty(ExpandoColumnConstants.INDEX_TYPE));
065
066 if (indexType != ExpandoColumnConstants.INDEX_TYPE_NONE) {
067 String fieldName = getExpandoFieldName(
068 searchContext, expandoBridge, attributeName);
069
070 if (searchContext.isAndSearch()) {
071 searchQuery.addRequiredTerm(fieldName, keywords);
072 }
073 else {
074 searchQuery.addTerm(fieldName, keywords);
075 }
076 }
077 }
078 }
079
080 @Override
081 protected BooleanQuery createFullQuery(
082 BooleanFilter fullQueryBooleanFilter, SearchContext searchContext)
083 throws Exception {
084
085 BooleanQuery searchQuery = new BooleanQueryImpl();
086
087 String keywords = searchContext.getKeywords();
088
089 if (Validator.isNotNull(keywords)) {
090 addSearchLocalizedTerm(
091 searchQuery, searchContext, Field.ASSET_CATEGORY_TITLES, false);
092
093 searchQuery.addExactTerm(Field.ASSET_TAG_NAMES, keywords);
094
095 int groupId = GetterUtil.getInteger(
096 searchContext.getAttribute(Field.GROUP_ID));
097
098 if (groupId == 0) {
099 fullQueryBooleanFilter.addTerm(
100 Field.STAGING_GROUP, "true", BooleanClauseOccur.MUST_NOT);
101 }
102
103 searchQuery.addTerms(Field.KEYWORDS, keywords);
104 }
105
106 List<Group> inactiveGroups = GroupLocalServiceUtil.getActiveGroups(
107 searchContext.getCompanyId(), false);
108
109 if (ListUtil.isNotEmpty(inactiveGroups)) {
110 TermsFilter groupIdTermsFilter = new TermsFilter(Field.GROUP_ID);
111
112 groupIdTermsFilter.addValues(
113 ArrayUtil.toStringArray(
114 ListUtil.toArray(inactiveGroups, Group.GROUP_ID_ACCESSOR)));
115
116 fullQueryBooleanFilter.add(
117 groupIdTermsFilter, BooleanClauseOccur.MUST_NOT);
118 }
119
120 for (String entryClassName : searchContext.getEntryClassNames()) {
121 Indexer<?> indexer = IndexerRegistryUtil.getIndexer(entryClassName);
122
123 if (indexer == null) {
124 continue;
125 }
126
127 String searchEngineId = searchContext.getSearchEngineId();
128
129 if (!searchEngineId.equals(indexer.getSearchEngineId())) {
130 continue;
131 }
132
133 if (Validator.isNotNull(keywords)) {
134 addSearchExpandoKeywords(
135 searchQuery, searchContext, keywords, entryClassName);
136 }
137
138 indexer.postProcessSearchQuery(
139 searchQuery, fullQueryBooleanFilter, searchContext);
140
141 for (IndexerPostProcessor indexerPostProcessor :
142 indexer.getIndexerPostProcessors()) {
143
144 indexerPostProcessor.postProcessSearchQuery(
145 searchQuery, fullQueryBooleanFilter, searchContext);
146 }
147
148 doPostProcessSearchQuery(indexer, searchQuery, searchContext);
149 }
150
151 Map<String, Facet> facets = searchContext.getFacets();
152
153 BooleanFilter facetBooleanFilter = new BooleanFilter();
154
155 for (Facet facet : facets.values()) {
156 BooleanClause<Filter> facetClause =
157 facet.getFacetFilterBooleanClause();
158
159 if (facetClause != null) {
160 facetBooleanFilter.add(
161 facetClause.getClause(),
162 facetClause.getBooleanClauseOccur());
163 }
164 }
165
166 addFacetClause(searchContext, facetBooleanFilter, facets.values());
167
168 if (facetBooleanFilter.hasClauses()) {
169 fullQueryBooleanFilter.add(
170 facetBooleanFilter, BooleanClauseOccur.MUST);
171 }
172
173 BooleanQuery fullQuery = new BooleanQueryImpl();
174
175 if (fullQueryBooleanFilter.hasClauses()) {
176 fullQuery.setPreBooleanFilter(fullQueryBooleanFilter);
177 }
178
179 if (searchQuery.hasClauses()) {
180 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
181 }
182
183 BooleanClause<Query>[] booleanClauses =
184 searchContext.getBooleanClauses();
185
186 if (booleanClauses != null) {
187 for (BooleanClause<Query> booleanClause : booleanClauses) {
188 fullQuery.add(
189 booleanClause.getClause(),
190 booleanClause.getBooleanClauseOccur());
191 }
192 }
193
194 for (String entryClassName : searchContext.getEntryClassNames()) {
195 Indexer<?> indexer = IndexerRegistryUtil.getIndexer(entryClassName);
196
197 if (indexer == null) {
198 continue;
199 }
200
201 String searchEngineId = searchContext.getSearchEngineId();
202
203 if (!searchEngineId.equals(indexer.getSearchEngineId())) {
204 continue;
205 }
206
207 for (IndexerPostProcessor indexerPostProcessor :
208 indexer.getIndexerPostProcessors()) {
209
210 indexerPostProcessor.postProcessFullQuery(
211 fullQuery, searchContext);
212 }
213 }
214
215 return fullQuery;
216 }
217
218 @Override
219 protected Hits doSearch(SearchContext searchContext)
220 throws SearchException {
221
222 try {
223 searchContext.setSearchEngineId(getSearchEngineId());
224
225 BooleanFilter queryBooleanFilter = new BooleanFilter();
226
227 queryBooleanFilter.addRequiredTerm(
228 Field.COMPANY_ID, searchContext.getCompanyId());
229
230 Query fullQuery = createFullQuery(
231 queryBooleanFilter, searchContext);
232
233 if (!fullQuery.hasChildren()) {
234 BooleanFilter preBooleanFilter =
235 fullQuery.getPreBooleanFilter();
236
237 fullQuery = new MatchAllQuery();
238
239 fullQuery.setPreBooleanFilter(preBooleanFilter);
240 }
241
242 QueryConfig queryConfig = searchContext.getQueryConfig();
243
244 fullQuery.setQueryConfig(queryConfig);
245
246 return IndexSearcherHelperUtil.search(searchContext, fullQuery);
247 }
248 catch (Exception e) {
249 throw new SearchException(e);
250 }
251 }
252
253 @Override
254 protected boolean isUseSearchResultPermissionFilter(
255 SearchContext searchContext) {
256
257 if (searchContext.getEntryClassNames() == null) {
258 return super.isFilterSearch();
259 }
260
261 for (String entryClassName : searchContext.getEntryClassNames()) {
262 Indexer<?> indexer = IndexerRegistryUtil.getIndexer(entryClassName);
263
264 if (indexer == null) {
265 continue;
266 }
267
268 if (indexer.isFilterSearch()) {
269 return true;
270 }
271 }
272
273 return super.isFilterSearch();
274 }
275
276 }