/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.search.solr.internal.groupby;
import static org.apache.solr.common.params.GroupParams.GROUP;
import static org.apache.solr.common.params.GroupParams.GROUP_FIELD;
import static org.apache.solr.common.params.GroupParams.GROUP_FORMAT;
import static org.apache.solr.common.params.GroupParams.GROUP_LIMIT;
import static org.apache.solr.common.params.GroupParams.GROUP_OFFSET;
import static org.apache.solr.common.params.GroupParams.GROUP_TOTAL_COUNT;
import com.liferay.portal.kernel.search.DocumentImpl;
import com.liferay.portal.kernel.search.GroupBy;
import com.liferay.portal.kernel.search.QueryConfig;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.Sort;
import com.liferay.portal.kernel.search.highlight.HighlightUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.search.solr.groupby.GroupByTranslator;
import com.liferay.portal.search.solr.internal.pagination.Pagination;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrQuery.SortClause;
import org.osgi.service.component.annotations.Component;
/**
* @author Miguel Angelo Caldas Gallindo
*/
@Component(immediate = true, service = GroupByTranslator.class)
public class DefaultGroupByTranslator implements GroupByTranslator {
@Override
public void translate(
SolrQuery solrQuery, SearchContext searchContext, int start, int end) {
GroupBy groupBy = searchContext.getGroupBy();
configureGroups(solrQuery, searchContext, start, end, groupBy);
}
protected void addHighlightedField(
SolrQuery solrQuery, QueryConfig queryConfig, String fieldName) {
solrQuery.addHighlightField(fieldName);
String localizedFieldName = DocumentImpl.getLocalizedName(
queryConfig.getLocale(), fieldName);
solrQuery.addHighlightField(localizedFieldName);
}
protected void addHighlights(SolrQuery solrQuery, QueryConfig queryConfig) {
if (!queryConfig.isHighlightEnabled()) {
return;
}
solrQuery.setHighlight(true);
solrQuery.setHighlightFragsize(queryConfig.getHighlightFragmentSize());
solrQuery.setHighlightRequireFieldMatch(
queryConfig.isHighlightRequireFieldMatch());
solrQuery.setHighlightSimplePost(HighlightUtil.HIGHLIGHT_TAG_CLOSE);
solrQuery.setHighlightSimplePre(HighlightUtil.HIGHLIGHT_TAG_OPEN);
solrQuery.setHighlightSnippets(queryConfig.getHighlightSnippetSize());
for (String highlightFieldName : queryConfig.getHighlightFieldNames()) {
addHighlightedField(solrQuery, queryConfig, highlightFieldName);
}
}
protected void addSorts(SolrQuery solrQuery, Sort[] sorts) {
if (ArrayUtil.isEmpty(sorts)) {
return;
}
Set<String> sortFieldNames = new HashSet<>(sorts.length);
for (Sort sort : sorts) {
if (sort == null) {
continue;
}
String sortFieldName = DocumentImpl.getSortFieldName(
sort, "_score");
if (sortFieldNames.contains(sortFieldName)) {
continue;
}
sortFieldNames.add(sortFieldName);
ORDER order = ORDER.asc;
if (sort.isReverse() || sortFieldName.equals("_score")) {
order = ORDER.desc;
}
solrQuery.addSort(new SortClause(sortFieldName, order));
}
}
protected void configureGroups(
SolrQuery solrQuery, SearchContext searchContext, int start, int end,
GroupBy groupBy) {
solrQuery.set(GROUP, true);
solrQuery.set(GROUP_FIELD, groupBy.getField());
solrQuery.set(GROUP_FORMAT, "grouped");
solrQuery.set(GROUP_TOTAL_COUNT, true);
Pagination pagination = new Pagination(start, end);
Optional<Integer> fromOptional;
int groupByStart = groupBy.getStart();
if (groupByStart != 0) {
fromOptional = Optional.of(groupByStart);
}
else {
fromOptional = pagination.getFrom();
}
fromOptional.ifPresent(from -> solrQuery.set(GROUP_OFFSET, from));
Optional<Integer> sizeOptional;
int groupBySize = groupBy.getSize();
if (groupBySize != 0) {
sizeOptional = Optional.of(groupBySize);
}
else {
sizeOptional = pagination.getSize();
}
solrQuery.set(GROUP_LIMIT, sizeOptional.orElse(3));
addHighlights(solrQuery, searchContext.getQueryConfig());
addSorts(solrQuery, searchContext.getSorts());
}
}