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