/* * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.data.solr.core.query; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.util.Assert; /** * Set of options that could be set for a {@link Query} in order to have grouped results. * * @author Francisco Spaeth * @since 1.4 */ public class GroupOptions { int DEFAULT_GROUP_LIMIT = 1; int DEFAULT_CACHE_PERCENT = 0; private List<Field> groupByFields = new ArrayList<>(0); private List<Function> groupByFunctions = new ArrayList<>(0); private List<Query> groupByQuery = new ArrayList<>(0); private Integer offset = null; private Integer limit = null; private Sort sort; private boolean truncateFacets = false; private boolean groupFacets = false; private boolean totalCount = false; private boolean groupMain = false; private int cachePercent = DEFAULT_CACHE_PERCENT; /** * Adds a group request for a {@link Field}. * * @param field * @return */ public GroupOptions addGroupByField(Field field) { Assert.notNull(field, "Field for grouping must not be null."); Assert.hasText(field.getName(), "Field.name for grouping must not be null/empty."); groupByFields.add(field); return this; } /** * List of {@link Field}s to perform grouping by. * * @return */ public List<Field> getGroupByFields() { return Collections.unmodifiableList(this.groupByFields); } /** * Adds a group request for a {@link Field} using its name. * * @param fieldName * @return */ public GroupOptions addGroupByField(String fieldName) { Assert.hasText(fieldName, "Field.name for grouping must not be null/empty."); groupByFields.add(new SimpleField(fieldName)); return this; } /** * Adds a group request for a {@link Function} result. * * @param function * @return */ public GroupOptions addGroupByFunction(Function function) { Assert.notNull(function, "Function for grouping must not be null."); groupByFunctions.add(function); return this; } /** * List of {@link Function}s to perform grouping by. * * @return */ public List<Function> getGroupByFunctions() { return Collections.unmodifiableList(groupByFunctions); } /** * Adds a group request for a {@link Query} result. * * @param query * @return */ public GroupOptions addGroupByQuery(Query query) { Assert.notNull(query, "Query for grouping must not be null."); groupByQuery.add(query); return this; } /** * List of {@link Query}s to perform grouping by. * * @return */ public List<Query> getGroupByQueries() { return Collections.unmodifiableList(groupByQuery); } /** * Sets the initial offset of each group. * * @param offset * @return */ public GroupOptions setOffset(Integer offset) { this.offset = offset == null ? null : Math.max(0, offset); return this; } /** * @return initial offset of each group */ public Integer getOffset() { return offset; } /** * @return the number of rows to return for each group. */ public Integer getLimit() { return limit; } /** * Sets the number of rows to return for each group. * * @param limit * @return */ public GroupOptions setLimit(Integer limit) { this.limit = limit; return this; } /** * Adds {@link Sort} to instruct how to sort elements within a single group. * * @param sort * @return */ public GroupOptions addSort(Sort sort) { if (sort == null) { return this; } if (this.sort == null) { this.sort = sort; } else { this.sort = this.sort.and(sort); } return this; } /** * @return sort instruction on how to sort elements within a single group. */ public Sort getSort() { return sort; } /** * Defines whether the group count should be included in the response. * * @param groupCount * @return */ public GroupOptions setTotalCount(boolean groupCount) { this.totalCount = groupCount; return this; } /** * @return whether the group count should be included in the response. */ public boolean isTotalCount() { return totalCount; } /** * Sets the caching for grouping results. * * @param cachePercent * @return */ public GroupOptions setCachePercent(int cachePercent) { this.cachePercent = Math.max(0, Math.min(100, cachePercent)); return this; } /** * @return caching for grouping results. */ public int getCachePercent() { return cachePercent; } /** * Defines the maximum size of the group cache. * * @param truncateFacets * @return */ public GroupOptions setTruncateFacets(boolean truncateFacets) { this.truncateFacets = truncateFacets; return this; } /** * @return the maximum size of the group cache. */ public boolean isTruncateFacets() { return truncateFacets; } /** * Defines whether field facet shall be computed in grouped fashion. * * @param groupFacets * @return */ public GroupOptions setGroupFacets(boolean groupFacets) { this.groupFacets = groupFacets; return this; } /** * @return whether field facet shall be computed in grouped fashion. */ public boolean isGroupFacets() { return groupFacets; } /** * Defines whether or not the first field group result shall be used as main result. * * @param groupMain * @return */ public GroupOptions setGroupMain(boolean groupMain) { this.groupMain = groupMain; return this; } /** * @return whether or not the first field group result shall be used as main result. */ public boolean isGroupMain() { return groupMain; } public Pageable getPageRequest() { if (this.limit == null && this.offset == null) { return null; } int limit = this.limit != null ? this.limit : DEFAULT_GROUP_LIMIT; int offset = this.offset != null ? this.offset : 0; return new SolrPageRequest(limit != 0 ? offset / limit : 0, limit, this.sort); } }