blob: 868fbf16360ec5cf071610e4eb6a2f1d6fafe7ef [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.lucene.search;
import java.io.IOException;
import java.util.Arrays;
/**
* Encapsulates sort criteria for returned hits.
*
* <p>A {@link Sort} can be created with an empty constructor, yielding an object that will instruct
* searches to return their hits sorted by relevance; or it can be created with one or more {@link
* SortField}s.
*
* @see SortField
* @since lucene 1.4
*/
public final class Sort {
/**
* Represents sorting by computed relevance. Using this sort criteria returns the same results as
* calling {@link IndexSearcher#search(Query,int) IndexSearcher#search()}without a sort criteria,
* only with slightly more overhead.
*/
public static final Sort RELEVANCE = new Sort();
/** Represents sorting by index order. */
public static final Sort INDEXORDER = new Sort(SortField.FIELD_DOC);
// internal representation of the sort criteria
private final SortField[] fields;
/**
* Sorts by computed relevance. This is the same sort criteria as calling {@link
* IndexSearcher#search(Query,int) IndexSearcher#search()}without a sort criteria, only with
* slightly more overhead.
*/
public Sort() {
this(SortField.FIELD_SCORE);
}
/**
* Sets the sort to the given criteria in succession: the first SortField is checked first, but if
* it produces a tie, then the second SortField is used to break the tie, etc. Finally, if there
* is still a tie after all SortFields are checked, the internal Lucene docid is used to break it.
*/
public Sort(SortField... fields) {
if (fields.length == 0) {
throw new IllegalArgumentException("There must be at least 1 sort field");
}
this.fields = fields;
}
/**
* Representation of the sort criteria.
*
* @return Array of SortField objects used in this sort criteria
*/
public SortField[] getSort() {
return fields;
}
/**
* Rewrites the SortFields in this Sort, returning a new Sort if any of the fields changes during
* their rewriting.
*
* @param searcher IndexSearcher to use in the rewriting
* @return {@code this} if the Sort/Fields have not changed, or a new Sort if there is a change
* @throws IOException Can be thrown by the rewriting
* @lucene.experimental
*/
public Sort rewrite(IndexSearcher searcher) throws IOException {
boolean changed = false;
SortField[] rewrittenSortFields = new SortField[fields.length];
for (int i = 0; i < fields.length; i++) {
rewrittenSortFields[i] = fields[i].rewrite(searcher);
if (fields[i] != rewrittenSortFields[i]) {
changed = true;
}
}
return changed ? new Sort(rewrittenSortFields) : this;
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < fields.length; i++) {
buffer.append(fields[i].toString());
if ((i + 1) < fields.length) buffer.append(',');
}
return buffer.toString();
}
/** Returns true if <code>o</code> is equal to this. */
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Sort)) return false;
final Sort other = (Sort) o;
return Arrays.equals(this.fields, other.fields);
}
/** Returns a hash code value for this object. */
@Override
public int hashCode() {
return 0x45aaf665 + Arrays.hashCode(fields);
}
/** Returns true if the relevance score is needed to sort documents. */
public boolean needsScores() {
for (SortField sortField : fields) {
if (sortField.needsScores()) {
return true;
}
}
return false;
}
}