1 package org.apache.lucene.search;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.Serializable;
21 import java.util.Arrays;
25 * Encapsulates sort criteria for returned hits.
27 * <p>The fields used to determine sort order must be carefully chosen.
28 * Documents must contain a single term in such a field,
29 * and the value of the term should indicate the document's relative position in
30 * a given sort order. The field must be indexed, but should not be tokenized,
31 * and does not need to be stored (unless you happen to want it back with the
32 * rest of your document data). In other words:
34 * <p><code>document.add (new Field ("byNumber", Integer.toString(x), Field.Store.NO, Field.Index.NOT_ANALYZED));</code></p>
37 * <p><h3>Valid Types of Values</h3>
39 * <p>There are four possible kinds of term values which may be put into
40 * sorting fields: Integers, Longs, Floats, or Strings. Unless
41 * {@link SortField SortField} objects are specified, the type of value
42 * in the field is determined by parsing the first term in the field.
44 * <p>Integer term values should contain only digits and an optional
45 * preceding negative sign. Values must be base 10 and in the range
46 * <code>Integer.MIN_VALUE</code> and <code>Integer.MAX_VALUE</code> inclusive.
47 * Documents which should appear first in the sort
48 * should have low value integers, later documents high values
49 * (i.e. the documents should be numbered <code>1..n</code> where
50 * <code>1</code> is the first and <code>n</code> the last).
52 * <p>Long term values should contain only digits and an optional
53 * preceding negative sign. Values must be base 10 and in the range
54 * <code>Long.MIN_VALUE</code> and <code>Long.MAX_VALUE</code> inclusive.
55 * Documents which should appear first in the sort
56 * should have low value integers, later documents high values.
58 * <p>Float term values should conform to values accepted by
59 * {@link Float Float.valueOf(String)} (except that <code>NaN</code>
60 * and <code>Infinity</code> are not supported).
61 * Documents which should appear first in the sort
62 * should have low values, later documents high values.
64 * <p>String term values can contain any valid String, but should
65 * not be tokenized. The values are sorted according to their
66 * {@link Comparable natural order}. Note that using this type
67 * of term value has higher memory requirements than the other
70 * <p><h3>Object Reuse</h3>
72 * <p>One of these objects can be
73 * used multiple times and the sort order changed between usages.
75 * <p>This class is thread safe.
77 * <p><h3>Memory Usage</h3>
79 * <p>Sorting uses of caches of term values maintained by the
80 * internal HitQueue(s). The cache is static and contains an integer
81 * or float array of length <code>IndexReader.maxDoc()</code> for each field
82 * name for which a sort is performed. In other words, the size of the
85 * <p><code>4 * IndexReader.maxDoc() * (# of different fields actually used to sort)</code>
87 * <p>For String fields, the cache is larger: in addition to the
88 * above array, the value of every term in the field is kept in memory.
89 * If there are many unique terms in the field, this could
92 * <p>Note that the size of the cache is not affected by how many
93 * fields are in the index and <i>might</i> be used to sort - only by
94 * the ones actually used to sort a result set.
96 * <p>Created: Feb 12, 2004 10:53:57 AM
101 implements Serializable {
104 * Represents sorting by computed relevance. Using this sort criteria returns
105 * the same results as calling
106 * {@link Searcher#search(Query,int) Searcher#search()}without a sort criteria,
107 * only with slightly more overhead.
109 public static final Sort RELEVANCE = new Sort();
111 /** Represents sorting by index order. */
112 public static final Sort INDEXORDER = new Sort(SortField.FIELD_DOC);
114 // internal representation of the sort criteria
118 * Sorts by computed relevance. This is the same sort criteria as calling
119 * {@link Searcher#search(Query,int) Searcher#search()}without a sort criteria,
120 * only with slightly more overhead.
123 this(SortField.FIELD_SCORE);
126 /** Sorts by the criteria in the given SortField. */
127 public Sort(SortField field) {
131 /** Sorts in succession by the criteria in each SortField. */
132 public Sort(SortField... fields) {
136 /** Sets the sort to the given criteria. */
137 public void setSort(SortField field) {
138 this.fields = new SortField[] { field };
141 /** Sets the sort to the given criteria in succession. */
142 public void setSort(SortField... fields) {
143 this.fields = fields;
147 * Representation of the sort criteria.
148 * @return Array of SortField objects used in this sort criteria
150 public SortField[] getSort() {
155 public String toString() {
156 StringBuilder buffer = new StringBuilder();
158 for (int i = 0; i < fields.length; i++) {
159 buffer.append(fields[i].toString());
160 if ((i+1) < fields.length)
164 return buffer.toString();
167 /** Returns true if <code>o</code> is equal to this. */
169 public boolean equals(Object o) {
170 if (this == o) return true;
171 if (!(o instanceof Sort)) return false;
172 final Sort other = (Sort)o;
173 return Arrays.equals(this.fields, other.fields);
176 /** Returns a hash code value for this object. */
178 public int hashCode() {
179 return 0x45aaf665 + Arrays.hashCode(fields);