LUCENE-1972: Remove deprecated ExtendedFieldCache, custom and auto caches, SortField.AUTO, deprecated custom sort, deprecated sorting HitCollectors, deprecated TopDocs HitCollectors, legacy search

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@824697 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2009-10-13 11:18:25 +00:00
parent 9f907beceb
commit 594c9a35f7
28 changed files with 152 additions and 1663 deletions

View File

@ -56,6 +56,11 @@ API Changes
* LUCENE-1975: Remove deprecated SpanQuery.getTerms() and generify
Query.extractTerms(Set<Term>) (Michael Busch)
* LUCENE-1972: Remove deprecated ExtendedFieldCache, custom and auto
caches, SortField.AUTO, deprecated custom sort, deprecated sorting
HitCollectors, deprecated TopDocs HitCollectors, legacy search
(Uwe Schindler)
Bug fixes
* LUCENE-1951: When the text provided to WildcardQuery has no wildcard

View File

@ -42,7 +42,7 @@
<property name="Name" value="Lucene"/>
<property name="dev.version" value="3.0-dev"/>
<property name="version" value="${dev.version}"/>
<property name="compatibility.tag" value="lucene_2_9_back_compat_tests_20091013a"/>
<property name="compatibility.tag" value="lucene_2_9_back_compat_tests_20091013b"/>
<property name="spec.version" value="${version}"/>
<property name="year" value="2000-${current.year}"/>
<property name="final.name" value="lucene-${name}-${version}"/>

View File

@ -23,7 +23,7 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
@ -39,10 +39,9 @@ public class TestEmptyIndex extends TestCase {
IndexReader r = new InstantiatedIndexReader(ii);
IndexSearcher s = new IndexSearcher(r);
TopDocCollector c = new TopDocCollector(1);
s.search(new TermQuery(new Term("foo", "bar")), c);
TopDocs td = s.search(new TermQuery(new Term("foo", "bar")), 1);
assertEquals(0, c.getTotalHits());
assertEquals(0, td.totalHits);
s.close();
r.close();

View File

@ -43,8 +43,6 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.util.AttributeImpl;
/**

View File

@ -17,12 +17,12 @@ package org.apache.lucene.store.instantiated;
import junit.framework.TestCase;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.search.HitCollector;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexReader;
/**
* Assert that the content of an index
@ -62,9 +62,12 @@ public class TestRealTime extends TestCase {
}
public static class Collector extends HitCollector {
public static class Collector extends org.apache.lucene.search.Collector {
private int hits = 0;
public void collect(int doc, float score) {
public void setScorer(Scorer scorer) {}
public void setNextReader(IndexReader reader, int docBase) {}
public boolean acceptsDocsOutOfOrder() { return true; }
public void collect(int doc) {
hits++;
}
}

View File

@ -236,29 +236,6 @@ public class TestRemoteSort extends LuceneTestCase implements Serializable {
runMultiSorts(multi, true); // this runs on the full index
}
// test custom search when remote
/* rewrite with new API
public void testRemoteCustomSort() throws Exception {
Searchable searcher = getRemote();
MultiSearcher multi = new MultiSearcher (new Searchable[] { searcher });
sort.setSort (new SortField ("custom", SampleComparable.getComparatorSource()));
assertMatches (multi, queryX, sort, "CAIEG");
sort.setSort (new SortField ("custom", SampleComparable.getComparatorSource(), true));
assertMatches (multi, queryY, sort, "HJDBF");
assertSaneFieldCaches(getName() + " ComparatorSource");
FieldCache.DEFAULT.purgeAllCaches();
SortComparator custom = SampleComparable.getComparator();
sort.setSort (new SortField ("custom", custom));
assertMatches (multi, queryX, sort, "CAIEG");
sort.setSort (new SortField ("custom", custom, true));
assertMatches (multi, queryY, sort, "HJDBF");
assertSaneFieldCaches(getName() + " Comparator");
FieldCache.DEFAULT.purgeAllCaches();
}*/
// test that the relevancy scores are the same even if
// hits are sorted
public void testNormalizedScores() throws Exception {
@ -283,32 +260,32 @@ public class TestRemoteSort extends LuceneTestCase implements Serializable {
assertSameValues (scoresY, getScores (remote.search (queryY, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresA, getScores (remote.search (queryA, null, 1000, sort).scoreDocs, remote));
sort.setSort ("int");
sort.setSort (new SortField("int", SortField.INT));
assertSameValues (scoresX, getScores (remote.search (queryX, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresY, getScores (remote.search (queryY, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresA, getScores (remote.search (queryA, null, 1000, sort).scoreDocs, remote));
sort.setSort ("float");
sort.setSort (new SortField("float", SortField.FLOAT));
assertSameValues (scoresX, getScores (remote.search (queryX, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresY, getScores (remote.search (queryY, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresA, getScores (remote.search (queryA, null, 1000, sort).scoreDocs, remote));
sort.setSort ("string");
sort.setSort (new SortField("string", SortField.STRING));
assertSameValues (scoresX, getScores (remote.search (queryX, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresY, getScores (remote.search (queryY, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresA, getScores (remote.search (queryA, null, 1000, sort).scoreDocs, remote));
sort.setSort (new String[] {"int","float"});
sort.setSort (new SortField("int", SortField.INT), new SortField("float", SortField.FLOAT));
assertSameValues (scoresX, getScores (remote.search (queryX, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresY, getScores (remote.search (queryY, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresA, getScores (remote.search (queryA, null, 1000, sort).scoreDocs, remote));
sort.setSort (new SortField[] { new SortField ("int", SortField.INT, true), new SortField (null, SortField.DOC, true) });
sort.setSort (new SortField ("int", SortField.INT, true), new SortField (null, SortField.DOC, true) );
assertSameValues (scoresX, getScores (remote.search (queryX, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresY, getScores (remote.search (queryY, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresA, getScores (remote.search (queryA, null, 1000, sort).scoreDocs, remote));
sort.setSort (new String[] {"float","string"});
sort.setSort (new SortField("float", SortField.FLOAT), new SortField("string", SortField.STRING));
assertSameValues (scoresX, getScores (remote.search (queryX, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresY, getScores (remote.search (queryY, null, 1000, sort).scoreDocs, remote));
assertSameValues (scoresA, getScores (remote.search (queryA, null, 1000, sort).scoreDocs, remote));
@ -324,52 +301,48 @@ public class TestRemoteSort extends LuceneTestCase implements Serializable {
expected = isFull ? "IDHFGJABEC" : "IDHFGJAEBC";
assertMatches(multi, queryA, sort, expected);
sort.setSort(new SortField[] {new SortField ("int", SortField.INT), SortField.FIELD_DOC});
sort.setSort(new SortField ("int", SortField.INT), SortField.FIELD_DOC);
expected = isFull ? "IDHFGJABEC" : "IDHFGJAEBC";
assertMatches(multi, queryA, sort, expected);
sort.setSort("int");
expected = isFull ? "IDHFGJABEC" : "IDHFGJAEBC";
assertMatches(multi, queryA, sort, expected);
sort.setSort(new SortField[] {new SortField ("float", SortField.FLOAT), SortField.FIELD_DOC});
sort.setSort(new SortField ("float", SortField.FLOAT), SortField.FIELD_DOC);
assertMatches(multi, queryA, sort, "GDHJCIEFAB");
sort.setSort("float");
sort.setSort(new SortField("float", SortField.FLOAT));
assertMatches(multi, queryA, sort, "GDHJCIEFAB");
sort.setSort("string");
sort.setSort(new SortField("string", SortField.STRING));
assertMatches(multi, queryA, sort, "DJAIHGFEBC");
sort.setSort("int", true);
sort.setSort(new SortField ("int", SortField.INT, true));
expected = isFull ? "CABEJGFHDI" : "CAEBJGFHDI";
assertMatches(multi, queryA, sort, expected);
sort.setSort("float", true);
sort.setSort(new SortField ("float", SortField.FLOAT, true));
assertMatches(multi, queryA, sort, "BAFECIJHDG");
sort.setSort("string", true);
sort.setSort(new SortField ("string", SortField.STRING, true));
assertMatches(multi, queryA, sort, "CBEFGHIAJD");
sort.setSort(new String[] {"int","float"});
sort.setSort(new SortField ("int", SortField.INT), new SortField ("float", SortField.FLOAT));
assertMatches(multi, queryA, sort, "IDHFGJEABC");
sort.setSort(new String[] {"float","string"});
sort.setSort(new SortField ("float", SortField.FLOAT), new SortField ("string", SortField.STRING));
assertMatches(multi, queryA, sort, "GDHJICEFAB");
sort.setSort("int");
sort.setSort(new SortField ("int", SortField.INT));
assertMatches(multi, queryF, sort, "IZJ");
sort.setSort("int", true);
sort.setSort(new SortField ("int", SortField.INT, true));
assertMatches(multi, queryF, sort, "JZI");
sort.setSort("float");
sort.setSort(new SortField ("float", SortField.FLOAT));
assertMatches(multi, queryF, sort, "ZJI");
sort.setSort("string");
sort.setSort(new SortField ("string", SortField.STRING));
assertMatches(multi, queryF, sort, "ZJI");
sort.setSort("string", true);
sort.setSort(new SortField ("string", SortField.STRING, true));
assertMatches(multi, queryF, sort, "IJZ");
// up to this point, all of the searches should have "sane"
@ -378,10 +351,10 @@ public class TestRemoteSort extends LuceneTestCase implements Serializable {
// next we'll check an alternate Locale for string, so purge first
FieldCache.DEFAULT.purgeAllCaches();
sort.setSort(new SortField[] { new SortField ("string", Locale.US) });
sort.setSort(new SortField ("string", Locale.US) );
assertMatches(multi, queryA, sort, "DJAIHGFEBC");
sort.setSort(new SortField[] { new SortField ("string", Locale.US, true)});
sort.setSort(new SortField ("string", Locale.US, true));
assertMatches(multi, queryA, sort, "CBEFGHIAJD");
assertSaneFieldCaches(getName() + " Locale.US");

View File

@ -1,50 +0,0 @@
package org.apache.lucene.search;
/**
* 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.
*/
import org.apache.lucene.index.IndexReader;
import java.io.IOException;
/**
* This interface is obsolete, use {@link FieldCache} instead.
*
* @deprecated Use {@link FieldCache}, this will be removed in Lucene 3.0
**/
public interface ExtendedFieldCache extends FieldCache {
/** @deprecated Use {@link FieldCache#DEFAULT}; this will be removed in Lucene 3.0 */
public static ExtendedFieldCache EXT_DEFAULT = (ExtendedFieldCache) FieldCache.DEFAULT;
/** @deprecated Use {@link FieldCache.LongParser}, this will be removed in Lucene 3.0 */
public interface LongParser extends FieldCache.LongParser {
}
/** @deprecated Use {@link FieldCache.DoubleParser}, this will be removed in Lucene 3.0 */
public interface DoubleParser extends FieldCache.DoubleParser {
}
/** @deprecated Will be removed in 3.0, this is for binary compatibility only */
public long[] getLongs(IndexReader reader, String field, ExtendedFieldCache.LongParser parser)
throws IOException;
/** @deprecated Will be removed in 3.0, this is for binary compatibility only */
public double[] getDoubles(IndexReader reader, String field, ExtendedFieldCache.DoubleParser parser)
throws IOException;
}

View File

@ -483,39 +483,6 @@ public interface FieldCache {
public StringIndex getStringIndex (IndexReader reader, String field)
throws IOException;
/** Checks the internal cache for an appropriate entry, and if
* none is found reads <code>field</code> to see if it contains integers, longs, floats
* or strings, and then calls one of the other methods in this class to get the
* values. For string values, a StringIndex is returned. After
* calling this method, there is an entry in the cache for both
* type <code>AUTO</code> and the actual found type.
* @param reader Used to get field values.
* @param field Which field contains the values.
* @return int[], long[], float[] or StringIndex.
* @throws IOException If any error occurs.
* @deprecated Please specify the exact type, instead.
* Especially, guessing does <b>not</b> work with the new
* {@link NumericField} type.
*/
public Object getAuto (IndexReader reader, String field)
throws IOException;
/** Checks the internal cache for an appropriate entry, and if none
* is found reads the terms out of <code>field</code> and calls the given SortComparator
* to get the sort values. A hit in the cache will happen if <code>reader</code>,
* <code>field</code>, and <code>comparator</code> are the same (using <code>equals()</code>)
* as a previous call to this method.
* @param reader Used to get field values.
* @param field Which field contains the values.
* @param comparator Used to convert terms into something to sort by.
* @return Array of sort objects, one for each document.
* @throws IOException If any error occurs.
* @deprecated Please implement {@link
* FieldComparatorSource} directly, instead.
*/
public Comparable[] getCustom (IndexReader reader, String field, SortComparator comparator)
throws IOException;
/**
* EXPERT: A unique Identifier/Description for each item in the FieldCache.
* Can be useful for logging/debugging.

View File

@ -43,8 +43,7 @@ import org.apache.lucene.util.FieldCacheSanityChecker;
*
* @since lucene 1.4
*/
// TODO: change interface to FieldCache in 3.0 when removed
class FieldCacheImpl implements ExtendedFieldCache {
class FieldCacheImpl implements FieldCache {
private Map caches;
FieldCacheImpl() {
@ -60,8 +59,6 @@ class FieldCacheImpl implements ExtendedFieldCache {
caches.put(Double.TYPE, new DoubleCache(this));
caches.put(String.class, new StringCache(this));
caches.put(StringIndex.class, new StringIndexCache(this));
caches.put(Comparable.class, new CustomCache(this));
caches.put(Object.class, new AutoCache(this));
}
public void purgeAllCaches() {
@ -524,12 +521,6 @@ class FieldCacheImpl implements ExtendedFieldCache {
return (long[]) ((Cache)caches.get(Long.TYPE)).get(reader, new Entry(field, parser));
}
/** @deprecated Will be removed in 3.0, this is for binary compatibility only */
public long[] getLongs(IndexReader reader, String field, ExtendedFieldCache.LongParser parser)
throws IOException {
return (long[]) ((Cache)caches.get(Long.TYPE)).get(reader, new Entry(field, parser));
}
static final class LongCache extends Cache {
LongCache(FieldCache wrapper) {
super(wrapper);
@ -585,12 +576,6 @@ class FieldCacheImpl implements ExtendedFieldCache {
return (double[]) ((Cache)caches.get(Double.TYPE)).get(reader, new Entry(field, parser));
}
/** @deprecated Will be removed in 3.0, this is for binary compatibility only */
public double[] getDoubles(IndexReader reader, String field, ExtendedFieldCache.DoubleParser parser)
throws IOException {
return (double[]) ((Cache)caches.get(Double.TYPE)).get(reader, new Entry(field, parser));
}
static final class DoubleCache extends Cache {
DoubleCache(FieldCache wrapper) {
super(wrapper);
@ -736,109 +721,6 @@ class FieldCacheImpl implements ExtendedFieldCache {
}
};
/** The pattern used to detect integer values in a field */
/** removed for java 1.3 compatibility
protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
**/
/** The pattern used to detect float values in a field */
/**
* removed for java 1.3 compatibility
* protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
*/
// inherit javadocs
public Object getAuto(IndexReader reader, String field) throws IOException {
return ((Cache)caches.get(Object.class)).get(reader, new Entry(field, (Parser)null));
}
/**
* @deprecated Please specify the exact type, instead.
* Especially, guessing does <b>not</b> work with the new
* {@link NumericField} type.
*/
static final class AutoCache extends Cache {
AutoCache(FieldCache wrapper) {
super(wrapper);
}
protected Object createValue(IndexReader reader, Entry entryKey)
throws IOException {
String field = StringHelper.intern((String) entryKey.field);
TermEnum enumerator = reader.terms (new Term (field));
try {
Term term = enumerator.term();
if (term == null) {
throw new RuntimeException ("no terms in field " + field + " - cannot determine type");
}
Object ret = null;
if (term.field() == field) {
String termtext = term.text().trim();
try {
Integer.parseInt (termtext);
ret = wrapper.getInts (reader, field);
} catch (NumberFormatException nfe1) {
try {
Long.parseLong(termtext);
ret = wrapper.getLongs (reader, field);
} catch (NumberFormatException nfe2) {
try {
Float.parseFloat (termtext);
ret = wrapper.getFloats (reader, field);
} catch (NumberFormatException nfe3) {
ret = wrapper.getStringIndex (reader, field);
}
}
}
} else {
throw new RuntimeException ("field \"" + field + "\" does not appear to be indexed");
}
return ret;
} finally {
enumerator.close();
}
}
};
/** @deprecated */
public Comparable[] getCustom(IndexReader reader, String field,
SortComparator comparator) throws IOException {
return (Comparable[]) ((Cache)caches.get(Comparable.class)).get(reader, new Entry(field, comparator));
}
/** @deprecated */
static final class CustomCache extends Cache {
CustomCache(FieldCache wrapper) {
super(wrapper);
}
protected Object createValue(IndexReader reader, Entry entryKey)
throws IOException {
Entry entry = (Entry) entryKey;
String field = entry.field;
SortComparator comparator = (SortComparator) entry.custom;
final Comparable[] retArray = new Comparable[reader.maxDoc()];
TermDocs termDocs = reader.termDocs();
TermEnum termEnum = reader.terms (new Term (field));
try {
do {
Term term = termEnum.term();
if (term==null || term.field() != field) break;
Comparable termval = comparator.getComparable (term.text());
termDocs.seek (termEnum);
while (termDocs.next()) {
retArray[termDocs.doc()] = termval;
}
} while (termEnum.next());
} finally {
termDocs.close();
termEnum.close();
}
return retArray;
}
};
private volatile PrintStream infoStream;
public void setInfoStream(PrintStream stream) {

View File

@ -33,8 +33,6 @@ import java.util.Locale;
class FieldDocSortedHitQueue
extends PriorityQueue<FieldDoc> {
// this cannot contain AUTO fields - any AUTO fields should
// have been resolved by the time this class is used.
volatile SortField[] fields;
// used in the case where the fields are sorted by locale
@ -63,10 +61,8 @@ extends PriorityQueue<FieldDoc> {
* @param fields
*/
synchronized void setFields (SortField[] fields) {
if (this.fields == null) {
this.fields = fields;
this.collators = hasCollators (fields);
}
this.fields = fields;
this.collators = hasCollators (fields);
}
@ -174,13 +170,6 @@ extends PriorityQueue<FieldDoc> {
c = docA.fields[i].compareTo (docB.fields[i]);
break;
}
case SortField.AUTO:{
// we cannot handle this - even if we determine the type of object (Float or
// Integer), we don't necessarily know how to compare them (both SCORE and
// FLOAT contain floats, but are sorted opposite of each other). Before
// we get here, each AUTO should have been replaced with its actual value.
throw new RuntimeException ("FieldDocSortedHitQueue cannot use an AUTO SortField");
}
default:{
throw new RuntimeException ("invalid SortField type: "+type);
}

View File

@ -1,501 +0,0 @@
package org.apache.lucene.search;
/**
* 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.
*/
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.util.PriorityQueue;
import java.io.IOException;
import java.text.Collator;
import java.util.Locale;
/**
* Expert: A hit queue for sorting by hits by terms in more than one field.
* Uses <code>FieldCache.DEFAULT</code> for maintaining internal term lookup tables.
*
* <p>Created: Dec 8, 2003 12:56:03 PM
*
* @since lucene 1.4
* @see Searcher#search(Query,Filter,int,Sort)
* @see FieldCache
* @deprecated see {@link FieldValueHitQueue}
*/
public class FieldSortedHitQueue
extends PriorityQueue {
/**
* Creates a hit queue sorted by the given list of fields.
* @param reader Index to use.
* @param fields Fieldable names, in priority order (highest priority first). Cannot be <code>null</code> or empty.
* @param size The number of hits to retain. Must be greater than zero.
* @throws IOException
*/
public FieldSortedHitQueue (IndexReader reader, SortField[] fields, int size)
throws IOException {
final int n = fields.length;
comparators = new ScoreDocComparator[n];
this.fields = new SortField[n];
for (int i=0; i<n; ++i) {
String fieldname = fields[i].getField();
comparators[i] = getCachedComparator (reader, fieldname, fields[i].getType(), fields[i].getParser(), fields[i].getLocale(), fields[i].getFactory());
// new SortField instances must only be created when auto-detection is in use
if (fields[i].getType() == SortField.AUTO) {
if (comparators[i].sortType() == SortField.STRING) {
this.fields[i] = new SortField (fieldname, fields[i].getLocale(), fields[i].getReverse());
} else {
this.fields[i] = new SortField (fieldname, comparators[i].sortType(), fields[i].getReverse());
}
} else {
assert comparators[i].sortType() == fields[i].getType();
this.fields[i] = fields[i];
}
}
initialize (size);
}
/** Stores a comparator corresponding to each field being sorted by */
protected ScoreDocComparator[] comparators;
/** Stores the sort criteria being used. */
protected SortField[] fields;
/** Stores the maximum score value encountered, needed for normalizing. */
protected float maxscore = Float.NEGATIVE_INFINITY;
/** returns the maximum score encountered by elements inserted via insert()
*/
public float getMaxScore() {
return maxscore;
}
// Update maxscore.
private final void updateMaxScore(FieldDoc fdoc) {
maxscore = Math.max(maxscore, fdoc.score);
}
// This overrides PriorityQueue.insertWithOverflow() so that
// updateMaxScore(FieldDoc) that keeps track of the score isn't accidentally
// bypassed.
public Object insertWithOverflow(Object element) {
updateMaxScore((FieldDoc) element);
return super.insertWithOverflow(element);
}
/**
* Returns whether <code>a</code> is less relevant than <code>b</code>.
* @param a ScoreDoc
* @param b ScoreDoc
* @return <code>true</code> if document <code>a</code> should be sorted after document <code>b</code>.
*/
protected boolean lessThan (final Object a, final Object b) {
final ScoreDoc docA = (ScoreDoc) a;
final ScoreDoc docB = (ScoreDoc) b;
// run comparators
final int n = comparators.length;
int c = 0;
for (int i=0; i<n && c==0; ++i) {
c = (fields[i].reverse) ? comparators[i].compare (docB, docA)
: comparators[i].compare (docA, docB);
}
// avoid random sort order that could lead to duplicates (bug #31241):
if (c == 0)
return docA.doc > docB.doc;
return c > 0;
}
/**
* Given a FieldDoc object, stores the values used
* to sort the given document. These values are not the raw
* values out of the index, but the internal representation
* of them. This is so the given search hit can be collated
* by a MultiSearcher with other search hits.
* @param doc The FieldDoc to store sort values into.
* @return The same FieldDoc passed in.
* @see Searchable#search(Weight,Filter,int,Sort)
*/
FieldDoc fillFields (final FieldDoc doc) {
final int n = comparators.length;
final Comparable[] fields = new Comparable[n];
for (int i=0; i<n; ++i)
fields[i] = comparators[i].sortValue(doc);
doc.fields = fields;
//if (maxscore > 1.0f) doc.score /= maxscore; // normalize scores
return doc;
}
/** Returns the SortFields being used by this hit queue. */
SortField[] getFields() {
return fields;
}
static ScoreDocComparator getCachedComparator (IndexReader reader, String field, int type, FieldCache.Parser parser, Locale locale, SortComparatorSource factory)
throws IOException {
if (type == SortField.DOC) return ScoreDocComparator.INDEXORDER;
if (type == SortField.SCORE) return ScoreDocComparator.RELEVANCE;
FieldCacheImpl.Entry entry = (factory != null)
? new FieldCacheImpl.Entry (field, factory)
: ( (parser != null)
? new FieldCacheImpl.Entry (field, type, parser)
: new FieldCacheImpl.Entry (field, type, locale)
);
return (ScoreDocComparator)Comparators.get(reader, entry);
}
/** Internal cache of comparators. Similar to FieldCache, only
* caches comparators instead of term values. */
static final FieldCacheImpl.Cache Comparators = new FieldCacheImpl.Cache() {
protected Object createValue(IndexReader reader, FieldCacheImpl.Entry entryKey)
throws IOException {
FieldCacheImpl.Entry entry = (FieldCacheImpl.Entry) entryKey;
String fieldname = entry.field;
int type = entry.type;
Locale locale = entry.locale;
FieldCache.Parser parser = null;
SortComparatorSource factory = null;
if (entry.custom instanceof SortComparatorSource) {
factory = (SortComparatorSource) entry.custom;
} else {
parser = (FieldCache.Parser) entry.custom;
}
ScoreDocComparator comparator;
switch (type) {
case SortField.AUTO:
comparator = comparatorAuto (reader, fieldname);
break;
case SortField.INT:
comparator = comparatorInt (reader, fieldname, (FieldCache.IntParser)parser);
break;
case SortField.FLOAT:
comparator = comparatorFloat (reader, fieldname, (FieldCache.FloatParser)parser);
break;
case SortField.LONG:
comparator = comparatorLong(reader, fieldname, (FieldCache.LongParser)parser);
break;
case SortField.DOUBLE:
comparator = comparatorDouble(reader, fieldname, (FieldCache.DoubleParser)parser);
break;
case SortField.SHORT:
comparator = comparatorShort(reader, fieldname, (FieldCache.ShortParser)parser);
break;
case SortField.BYTE:
comparator = comparatorByte(reader, fieldname, (FieldCache.ByteParser)parser);
break;
case SortField.STRING:
if (locale != null) comparator = comparatorStringLocale (reader, fieldname, locale);
else comparator = comparatorString (reader, fieldname);
break;
case SortField.CUSTOM:
comparator = factory.newComparator (reader, fieldname);
break;
default:
throw new RuntimeException ("unknown field type: "+type);
}
return comparator;
}
};
/**
* Returns a comparator for sorting hits according to a field containing bytes.
* @param reader Index to use.
* @param fieldname Fieldable containing integer values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorByte(final IndexReader reader, final String fieldname, final FieldCache.ByteParser parser)
throws IOException {
final String field = fieldname.intern();
final byte[] fieldOrder = FieldCache.DEFAULT.getBytes(reader, field, parser);
return new ScoreDocComparator() {
public final int compare (final ScoreDoc i, final ScoreDoc j) {
final int fi = fieldOrder[i.doc];
final int fj = fieldOrder[j.doc];
if (fi < fj) return -1;
if (fi > fj) return 1;
return 0;
}
public Comparable sortValue (final ScoreDoc i) {
return Byte.valueOf(fieldOrder[i.doc]);
}
public int sortType() {
return SortField.BYTE;
}
};
}
/**
* Returns a comparator for sorting hits according to a field containing shorts.
* @param reader Index to use.
* @param fieldname Fieldable containing integer values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorShort(final IndexReader reader, final String fieldname, final FieldCache.ShortParser parser)
throws IOException {
final String field = fieldname.intern();
final short[] fieldOrder = FieldCache.DEFAULT.getShorts(reader, field, parser);
return new ScoreDocComparator() {
public final int compare (final ScoreDoc i, final ScoreDoc j) {
final int fi = fieldOrder[i.doc];
final int fj = fieldOrder[j.doc];
if (fi < fj) return -1;
if (fi > fj) return 1;
return 0;
}
public Comparable sortValue (final ScoreDoc i) {
return Short.valueOf(fieldOrder[i.doc]);
}
public int sortType() {
return SortField.SHORT;
}
};
}
/**
* Returns a comparator for sorting hits according to a field containing integers.
* @param reader Index to use.
* @param fieldname Fieldable containing integer values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorInt (final IndexReader reader, final String fieldname, final FieldCache.IntParser parser)
throws IOException {
final String field = fieldname.intern();
final int[] fieldOrder = FieldCache.DEFAULT.getInts(reader, field, parser);
return new ScoreDocComparator() {
public final int compare (final ScoreDoc i, final ScoreDoc j) {
final int fi = fieldOrder[i.doc];
final int fj = fieldOrder[j.doc];
if (fi < fj) return -1;
if (fi > fj) return 1;
return 0;
}
public Comparable sortValue (final ScoreDoc i) {
return Integer.valueOf(fieldOrder[i.doc]);
}
public int sortType() {
return SortField.INT;
}
};
}
/**
* Returns a comparator for sorting hits according to a field containing integers.
* @param reader Index to use.
* @param fieldname Fieldable containing integer values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorLong (final IndexReader reader, final String fieldname, final FieldCache.LongParser parser)
throws IOException {
final String field = fieldname.intern();
final long[] fieldOrder = FieldCache.DEFAULT.getLongs (reader, field, parser);
return new ScoreDocComparator() {
public final int compare (final ScoreDoc i, final ScoreDoc j) {
final long li = fieldOrder[i.doc];
final long lj = fieldOrder[j.doc];
if (li < lj) return -1;
if (li > lj) return 1;
return 0;
}
public Comparable sortValue (final ScoreDoc i) {
return Long.valueOf(fieldOrder[i.doc]);
}
public int sortType() {
return SortField.LONG;
}
};
}
/**
* Returns a comparator for sorting hits according to a field containing floats.
* @param reader Index to use.
* @param fieldname Fieldable containing float values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorFloat (final IndexReader reader, final String fieldname, final FieldCache.FloatParser parser)
throws IOException {
final String field = fieldname.intern();
final float[] fieldOrder = FieldCache.DEFAULT.getFloats (reader, field, parser);
return new ScoreDocComparator () {
public final int compare (final ScoreDoc i, final ScoreDoc j) {
final float fi = fieldOrder[i.doc];
final float fj = fieldOrder[j.doc];
if (fi < fj) return -1;
if (fi > fj) return 1;
return 0;
}
public Comparable sortValue (final ScoreDoc i) {
return Float.valueOf(fieldOrder[i.doc]);
}
public int sortType() {
return SortField.FLOAT;
}
};
}
/**
* Returns a comparator for sorting hits according to a field containing doubles.
* @param reader Index to use.
* @param fieldname Fieldable containing float values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorDouble(final IndexReader reader, final String fieldname, final FieldCache.DoubleParser parser)
throws IOException {
final String field = fieldname.intern();
final double[] fieldOrder = FieldCache.DEFAULT.getDoubles (reader, field, parser);
return new ScoreDocComparator () {
public final int compare (final ScoreDoc i, final ScoreDoc j) {
final double di = fieldOrder[i.doc];
final double dj = fieldOrder[j.doc];
if (di < dj) return -1;
if (di > dj) return 1;
return 0;
}
public Comparable sortValue (final ScoreDoc i) {
return Double.valueOf(fieldOrder[i.doc]);
}
public int sortType() {
return SortField.DOUBLE;
}
};
}
/**
* Returns a comparator for sorting hits according to a field containing strings.
* @param reader Index to use.
* @param fieldname Fieldable containing string values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorString (final IndexReader reader, final String fieldname)
throws IOException {
final String field = fieldname.intern();
final FieldCache.StringIndex index = FieldCache.DEFAULT.getStringIndex (reader, field);
return new ScoreDocComparator () {
public final int compare (final ScoreDoc i, final ScoreDoc j) {
final int fi = index.order[i.doc];
final int fj = index.order[j.doc];
if (fi < fj) return -1;
if (fi > fj) return 1;
return 0;
}
public Comparable sortValue (final ScoreDoc i) {
return index.lookup[index.order[i.doc]];
}
public int sortType() {
return SortField.STRING;
}
};
}
/**
* Returns a comparator for sorting hits according to a field containing strings.
* @param reader Index to use.
* @param fieldname Fieldable containing string values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorStringLocale (final IndexReader reader, final String fieldname, final Locale locale)
throws IOException {
final Collator collator = Collator.getInstance (locale);
final String field = fieldname.intern();
final String[] index = FieldCache.DEFAULT.getStrings (reader, field);
return new ScoreDocComparator() {
public final int compare(final ScoreDoc i, final ScoreDoc j) {
String is = index[i.doc];
String js = index[j.doc];
if (is == js) {
return 0;
} else if (is == null) {
return -1;
} else if (js == null) {
return 1;
} else {
return collator.compare(is, js);
}
}
public Comparable sortValue (final ScoreDoc i) {
return index[i.doc];
}
public int sortType() {
return SortField.STRING;
}
};
}
/**
* Returns a comparator for sorting hits according to values in the given field.
* The terms in the field are looked at to determine whether they contain integers,
* floats or strings. Once the type is determined, one of the other static methods
* in this class is called to get the comparator.
* @param reader Index to use.
* @param fieldname Fieldable containing values.
* @return Comparator for sorting hits.
* @throws IOException If an error occurs reading the index.
*/
static ScoreDocComparator comparatorAuto (final IndexReader reader, final String fieldname)
throws IOException {
final String field = fieldname.intern();
Object lookupArray = FieldCache.DEFAULT.getAuto (reader, field);
if (lookupArray instanceof FieldCache.StringIndex) {
return comparatorString (reader, field);
} else if (lookupArray instanceof int[]) {
return comparatorInt (reader, field, null);
} else if (lookupArray instanceof long[]) {
return comparatorLong (reader, field, null);
} else if (lookupArray instanceof float[]) {
return comparatorFloat (reader, field, null);
} else if (lookupArray instanceof String[]) {
return comparatorString (reader, field);
} else {
throw new RuntimeException ("unknown data type in field '"+field+"'");
}
}
}

View File

@ -26,11 +26,6 @@ import org.apache.lucene.util.PriorityQueue;
* Uses <code>FieldCache.DEFAULT</code> for maintaining
* internal term lookup tables.
*
* This class will not resolve SortField.AUTO types, and expects the type
* of all SortFields used for construction to already have been resolved.
* {@link SortField#detectFieldType(IndexReader, String)} is a utility method which
* may be used for field type detection.
*
* <b>NOTE:</b> This API is experimental and might change in
* incompatible ways in the next release.
*
@ -74,8 +69,6 @@ public abstract class FieldValueHitQueue extends PriorityQueue {
}
SortField field = fields[0];
// AUTO is resolved before we are called
assert field.getType() != SortField.AUTO;
comparator = field.getComparator(size, 0);
oneReverseMul = field.reverse ? -1 : 1;
@ -123,9 +116,6 @@ public abstract class FieldValueHitQueue extends PriorityQueue {
for (int i = 0; i < numComparators; ++i) {
SortField field = fields[i];
// AUTO is resolved before we are called
assert field.getType() != SortField.AUTO;
reverseMul[i] = field.reverse ? -1 : 1;
comparators[i] = field.getComparator(size, i);
}

View File

@ -173,40 +173,10 @@ public class IndexSearcher extends Searcher {
throws IOException {
SortField[] fields = sort.fields;
boolean legacy = false;
for(int i = 0; i < fields.length; i++) {
SortField field = fields[i];
String fieldname = field.getField();
int type = field.getType();
// Resolve AUTO into its true type
if (type == SortField.AUTO) {
int autotype = SortField.detectFieldType(reader, fieldname);
if (autotype == SortField.STRING) {
fields[i] = new SortField (fieldname, field.getLocale(), field.getReverse());
} else {
fields[i] = new SortField (fieldname, autotype, field.getReverse());
}
}
if (field.getUseLegacySearch()) {
legacy = true;
}
}
if (legacy) {
// Search the single top-level reader
TopDocCollector collector = new TopFieldDocCollector(reader, sort, nDocs);
HitCollectorWrapper hcw = new HitCollectorWrapper(collector);
hcw.setNextReader(reader, 0);
if (filter == null) {
Scorer scorer = weight.scorer(reader, true, true);
if (scorer != null) {
scorer.score(hcw);
}
} else {
searchWithFilter(reader, weight, filter, hcw);
}
return (TopFieldDocs) collector.topDocs();
}
TopFieldCollector collector = TopFieldCollector.create(sort, nDocs,

View File

@ -240,9 +240,6 @@ class MultiSearcherThread extends Thread {
this.ioe = ioe;
}
if (ioe == null) {
// if we are sorting by fields, we need to tell the field sorted hit queue
// the actual type of fields, in case the original list contained AUTO.
// if the searchable returns null for fields, we'll have problems.
if (sort != null) {
TopFieldDocs docsFields = (TopFieldDocs) docs;
// If one of the Sort fields is FIELD_DOC, need to fix its values, so that

View File

@ -1,43 +0,0 @@
package org.apache.lucene.search;
/**
* 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.
*/
/** Constrains search results to only match those which also match a provided
* query. Results are cached, so that searches after the first on the same
* index using this filter are much faster.
*
* @deprecated use a CachingWrapperFilter with QueryWrapperFilter
*/
public class QueryFilter extends CachingWrapperFilter {
/** Constructs a filter which only matches documents matching
* <code>query</code>.
*/
public QueryFilter(Query query) {
super(new QueryWrapperFilter(query));
}
public boolean equals(Object o) {
return super.equals((QueryFilter)o);
}
public int hashCode() {
return super.hashCode() ^ 0x923F64B9;
}
}

View File

@ -1,96 +0,0 @@
package org.apache.lucene.search;
/**
* 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.
*/
/**
* Expert: Compares two ScoreDoc objects for sorting.
*
* <p>Created: Feb 3, 2004 9:00:16 AM
*
* @since lucene 1.4
* @deprecated use {@link FieldComparator}
*/
public interface ScoreDocComparator {
/** Special comparator for sorting hits according to computed relevance (document score). */
static final ScoreDocComparator RELEVANCE = new ScoreDocComparator() {
public int compare (ScoreDoc i, ScoreDoc j) {
if (i.score > j.score) return -1;
if (i.score < j.score) return 1;
return 0;
}
public Comparable sortValue (ScoreDoc i) {
return Float.valueOf(i.score);
}
public int sortType() {
return SortField.SCORE;
}
};
/** Special comparator for sorting hits according to index order (document number). */
static final ScoreDocComparator INDEXORDER = new ScoreDocComparator() {
public int compare (ScoreDoc i, ScoreDoc j) {
if (i.doc < j.doc) return -1;
if (i.doc > j.doc) return 1;
return 0;
}
public Comparable sortValue (ScoreDoc i) {
return Integer.valueOf(i.doc);
}
public int sortType() {
return SortField.DOC;
}
};
/**
* Compares two ScoreDoc objects and returns a result indicating their
* sort order.
* @param i First ScoreDoc
* @param j Second ScoreDoc
* @return a negative integer if <code>i</code> should come before <code>j</code><br>
* a positive integer if <code>i</code> should come after <code>j</code><br>
* <code>0</code> if they are equal
* @see java.util.Comparator
*/
int compare (ScoreDoc i, ScoreDoc j);
/**
* Returns the value used to sort the given document. The
* object returned must implement the java.io.Serializable
* interface. This is used by multisearchers to determine how
* to collate results from their searchers.
* @see FieldDoc
* @param i Document
* @return Serializable object
*/
Comparable sortValue (ScoreDoc i);
/**
* Returns the type of sort. Should return <code>SortField.SCORE</code>,
* <code>SortField.DOC</code>, <code>SortField.STRING</code>,
* <code>SortField.INTEGER</code>, <code>SortField.FLOAT</code> or
* <code>SortField.CUSTOM</code>. It is not valid to return
* <code>SortField.AUTO</code>.
* This is used by multisearchers to determine how to collate results
* from their searchers.
* @return One of the constants in SortField.
* @see SortField
*/
int sortType();
}

View File

@ -123,99 +123,23 @@ implements Serializable {
this(SortField.FIELD_SCORE);
}
/**
* Sorts by the terms in <code>field</code> then by index order (document
* number). The type of value in <code>field</code> is determined
* automatically.
*
* @see SortField#AUTO
* @deprecated Please specify the type explicitly by
* first creating a {@link SortField} and then use {@link
* #Sort(SortField)}
*/
public Sort(String field) {
setSort(field, false);
}
/**
* Sorts possibly in reverse by the terms in <code>field</code> then by
* index order (document number). The type of value in <code>field</code> is
* determined automatically.
*
* @see SortField#AUTO
* @deprecated Please specify the type explicitly by
* first creating a {@link SortField} and then use {@link
* #Sort(SortField)}
*/
public Sort(String field, boolean reverse) {
setSort(field, reverse);
}
/**
* Sorts in succession by the terms in each field. The type of value in
* <code>field</code> is determined automatically.
*
* @see SortField#AUTO
* @deprecated Please specify the type explicitly by
* first creating {@link SortField}s and then use {@link
* #Sort(SortField[])}
*/
public Sort(String[] fields) {
setSort(fields);
}
/** Sorts by the criteria in the given SortField. */
public Sort(SortField field) {
setSort(field);
}
/** Sorts in succession by the criteria in each SortField. */
public Sort(SortField[] fields) {
public Sort(SortField... fields) {
setSort(fields);
}
/**
* Sets the sort to the terms in <code>field</code> then by index order
* (document number).
* @deprecated Please specify the type explicitly by
* first creating a {@link SortField} and then use {@link
* #setSort(SortField)}
*/
public final void setSort(String field) {
setSort(field, false);
}
/**
* Sets the sort to the terms in <code>field</code> possibly in reverse,
* then by index order (document number).
* @deprecated Please specify the type explicitly by
* first creating a {@link SortField} and then use {@link
* #setSort(SortField)}
*/
public void setSort(String field, boolean reverse) {
fields = new SortField[] { new SortField(field, SortField.AUTO, reverse) };
}
/** Sets the sort to the terms in each field in succession.
* @deprecated Please specify the type explicitly by
* first creating {@link SortField}s and then use {@link
* #setSort(SortField[])} */
public void setSort(String[] fieldnames) {
final int n = fieldnames.length;
SortField[] nfields = new SortField[n];
for (int i = 0; i < n; ++i) {
nfields[i] = new SortField(fieldnames[i], SortField.AUTO);
}
fields = nfields;
}
/** Sets the sort to the given criteria. */
public void setSort(SortField field) {
this.fields = new SortField[] { field };
}
/** Sets the sort to the given criteria in succession. */
public void setSort(SortField[] fields) {
public void setSort(SortField... fields) {
this.fields = fields;
}

View File

@ -1,90 +0,0 @@
package org.apache.lucene.search;
/**
* 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.
*/
import org.apache.lucene.index.IndexReader;
import java.io.IOException;
/**
* Abstract base class for sorting hits returned by a Query.
*
* <p>
* This class should only be used if the other SortField types (SCORE, DOC,
* STRING, INT, FLOAT) do not provide an adequate sorting. It maintains an
* internal cache of values which could be quite large. The cache is an array of
* Comparable, one for each document in the index. There is a distinct
* Comparable for each unique term in the field - if some documents have the
* same term in the field, the cache array will have entries which reference the
* same Comparable.
*
* This class will be used as part of a key to a FieldCache value. You must
* implement hashCode and equals to avoid an explosion in RAM usage if you use
* instances that are not the same instance. If you are searching using the
* Remote contrib, the same instance of this class on the client will be a new
* instance on every call to the server, so hashCode/equals is very important in
* that situation.
*
* <p>
* Created: Apr 21, 2004 5:08:38 PM
*
*
* @since 1.4
* @deprecated Please use {@link FieldComparatorSource} instead.
*/
public abstract class SortComparator
implements SortComparatorSource {
// inherit javadocs
public ScoreDocComparator newComparator (final IndexReader reader, final String fieldname)
throws IOException {
final String field = fieldname.intern();
final Comparable[] cachedValues = FieldCache.DEFAULT.getCustom (reader, field, SortComparator.this);
return new ScoreDocComparator() {
public int compare (ScoreDoc i, ScoreDoc j) {
return cachedValues[i.doc].compareTo (cachedValues[j.doc]);
}
public Comparable sortValue (ScoreDoc i) {
return cachedValues[i.doc];
}
public int sortType(){
return SortField.CUSTOM;
}
};
}
/**
* Returns an object which, when sorted according to natural order,
* will order the Term values in the correct order.
* <p>For example, if the Terms contained integer values, this method
* would return <code>Integer.valueOf(termtext)</code>. Note that this
* might not always be the most efficient implementation - for this
* particular example, a better implementation might be to make a
* ScoreDocLookupComparator that uses an internal lookup table of int.
* @param termtext The textual value of the term.
* @return An object representing <code>termtext</code> that sorts according to the natural order of <code>termtext</code>.
* @see Comparable
* @see ScoreDocComparator
*/
protected abstract Comparable getComparable (String termtext);
}

View File

@ -1,52 +0,0 @@
package org.apache.lucene.search;
/**
* 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.
*/
import org.apache.lucene.index.IndexReader;
import java.io.IOException;
import java.io.Serializable;
/**
* Expert: returns a comparator for sorting ScoreDocs.
*
* <p>
* Created: Apr 21, 2004 3:49:28 PM
*
* This class will be used as part of a key to a FieldCache value. You must
* implement hashCode and equals to avoid an explosion in RAM usage if you use
* instances that are not the same instance. If you are searching using the
* Remote contrib, the same instance of this class on the client will be a new
* instance on every call to the server, so hashCode/equals is very important in
* that situation.
*
* @since 1.4
* @deprecated Please use {@link FieldComparatorSource} instead.
*/
public interface SortComparatorSource
extends Serializable {
/**
* Creates a comparator for the field in the given index.
* @param reader Index to create comparator for.
* @param fieldname Name of the field to create comparator for.
* @return Comparator of ScoreDoc objects.
* @throws IOException If an error occurs reading the index.
*/
ScoreDocComparator newComparator (IndexReader reader, String fieldname)
throws IOException;
}

View File

@ -47,15 +47,7 @@ implements Serializable {
* values are at the front. */
public static final int DOC = 1;
/** Guess type of sort based on field contents. A regular expression is used
* to look at the first term indexed for the field and determine if it
* represents an integer number, a floating point number, or just arbitrary
* string characters.
* @deprecated Please specify the exact type, instead.
* Especially, guessing does <b>not</b> work with the new
* {@link NumericField} type.
*/
public static final int AUTO = 2;
// reserved, in Lucene 2.9, there was a constant: AUTO = 2;
/** Sort using term values as Strings. Sort values are String and lower
* values are at the front. */
@ -106,10 +98,9 @@ implements Serializable {
public static final SortField FIELD_DOC = new SortField (null, DOC);
private String field;
private int type = AUTO; // defaults to determining type dynamically
private int type; // defaults to determining type dynamically
private Locale locale; // defaults to "natural order" (no Locale)
boolean reverse = false; // defaults to natural order
private SortComparatorSource factory;
private FieldCache.Parser parser;
// Used for CUSTOM sort
@ -117,27 +108,6 @@ implements Serializable {
private boolean useLegacy = false; // remove in Lucene 3.0
/** Creates a sort by terms in the given field where the type of term value
* is determined dynamically ({@link #AUTO AUTO}).
* @param field Name of field to sort by, cannot be
* <code>null</code>.
* @deprecated Please specify the exact type instead.
*/
public SortField (String field) {
initFieldType(field, AUTO);
}
/** Creates a sort, possibly in reverse, by terms in the given field where
* the type of term value is determined dynamically ({@link #AUTO AUTO}).
* @param field Name of field to sort by, cannot be <code>null</code>.
* @param reverse True if natural order should be reversed.
* @deprecated Please specify the exact type instead.
*/
public SortField (String field, boolean reverse) {
initFieldType(field, AUTO);
this.reverse = reverse;
}
/** Creates a sort by terms in the given field with the type of term
* values explicitly given.
* @param field Name of field to sort by. Can be <code>null</code> if
@ -220,17 +190,6 @@ implements Serializable {
this.reverse = reverse;
}
/** Creates a sort with a custom comparison function.
* @param field Name of field to sort by; cannot be <code>null</code>.
* @param comparator Returns a comparator for sorting hits.
* @deprecated use SortField (String field, FieldComparatorSource comparator)
*/
public SortField (String field, SortComparatorSource comparator) {
initFieldType(field, CUSTOM);
setUseLegacySearch(true);
this.factory = comparator;
}
/** Creates a sort with a custom comparison function.
* @param field Name of field to sort by; cannot be <code>null</code>.
* @param comparator Returns a comparator for sorting hits.
@ -240,19 +199,6 @@ implements Serializable {
this.comparatorSource = comparator;
}
/** Creates a sort, possibly in reverse, with a custom comparison function.
* @param field Name of field to sort by; cannot be <code>null</code>.
* @param comparator Returns a comparator for sorting hits.
* @param reverse True if natural order should be reversed.
* @deprecated use SortField (String field, FieldComparatorSource comparator, boolean reverse)
*/
public SortField (String field, SortComparatorSource comparator, boolean reverse) {
initFieldType(field, CUSTOM);
setUseLegacySearch(true);
this.reverse = reverse;
this.factory = comparator;
}
/** Creates a sort, possibly in reverse, with a custom comparison function.
* @param field Name of field to sort by; cannot be <code>null</code>.
* @param comparator Returns a comparator for sorting hits.
@ -285,7 +231,7 @@ implements Serializable {
}
/** Returns the type of contents in the field.
* @return One of the constants SCORE, DOC, AUTO, STRING, INT or FLOAT.
* @return One of the constants SCORE, DOC, STRING, INT or FLOAT.
*/
public int getType() {
return type;
@ -314,37 +260,6 @@ implements Serializable {
return reverse;
}
/**
* @deprecated use {@link #getComparatorSource()}
*/
public SortComparatorSource getFactory() {
return factory;
}
public FieldComparatorSource getComparatorSource() {
return comparatorSource;
}
/**
* Use legacy IndexSearch implementation: search with a DirectoryReader rather
* than passing a single hit collector to multiple SegmentReaders.
*
* @param legacy true for legacy behavior
* @deprecated will be removed in Lucene 3.0.
*/
public void setUseLegacySearch(boolean legacy) {
this.useLegacy = legacy;
}
/**
* @return if true, IndexSearch will use legacy sorting search implementation.
* eg. multiple Priority Queues.
* @deprecated will be removed in Lucene 3.0.
*/
public boolean getUseLegacySearch() {
return this.useLegacy;
}
public String toString() {
StringBuilder buffer = new StringBuilder();
switch (type) {
@ -356,10 +271,6 @@ implements Serializable {
buffer.append("<doc>");
break;
case AUTO:
buffer.append("<auto: \"").append(field).append("\">");
break;
case STRING:
buffer.append("<string: \"").append(field).append("\">");
break;
@ -393,7 +304,7 @@ implements Serializable {
break;
case CUSTOM:
buffer.append("<custom:\"").append(field).append("\": ").append(factory).append('>');
buffer.append("<custom:\"").append(field).append("\": ").append(comparatorSource).append('>');
break;
default:
@ -409,7 +320,7 @@ implements Serializable {
}
/** Returns true if <code>o</code> is equal to this. If a
* {@link SortComparatorSource} (deprecated) or {@link
* {@link FieldComparatorSource} or {@link
* FieldCache.Parser} was provided, it must properly
* implement equals (unless a singleton is always used). */
public boolean equals(Object o) {
@ -421,14 +332,13 @@ implements Serializable {
&& other.type == this.type
&& other.reverse == this.reverse
&& (other.locale == null ? this.locale == null : other.locale.equals(this.locale))
&& (other.factory == null ? this.factory == null : other.factory.equals(this.factory))
&& (other.comparatorSource == null ? this.comparatorSource == null : other.comparatorSource.equals(this.comparatorSource))
&& (other.parser == null ? this.parser == null : other.parser.equals(this.parser))
);
}
/** Returns true if <code>o</code> is equal to this. If a
* {@link SortComparatorSource} (deprecated) or {@link
* {@link FieldComparatorSource} or {@link
* FieldCache.Parser} was provided, it must properly
* implement hashCode (unless a singleton is always
* used). */
@ -436,7 +346,6 @@ implements Serializable {
int hash=type^0x346565dd + Boolean.valueOf(reverse).hashCode()^0xaf5998bb;
if (field != null) hash += field.hashCode()^0xff5685dd;
if (locale != null) hash += locale.hashCode()^0x08150815;
if (factory != null) hash += factory.hashCode()^0x34987555;
if (comparatorSource != null) hash += comparatorSource.hashCode();
if (parser != null) hash += parser.hashCode()^0x3aaf56ff;
return hash;
@ -491,7 +400,7 @@ implements Serializable {
return new FieldComparator.ShortComparator(numHits, field, parser);
case SortField.CUSTOM:
assert factory == null && comparatorSource != null;
assert comparatorSource != null;
return comparatorSource.newComparator(field, numHits, sortPos, reverse);
case SortField.STRING:
@ -504,45 +413,4 @@ implements Serializable {
throw new IllegalStateException("Illegal sort type: " + type);
}
}
/**
* Attempts to detect the given field type for an IndexReader.
* @deprecated
*/
static int detectFieldType(IndexReader reader, String fieldKey) throws IOException {
String field = StringHelper.intern(fieldKey);
TermEnum enumerator = reader.terms(new Term(field));
try {
Term term = enumerator.term();
if (term == null) {
throw new RuntimeException("no terms in field " + field + " - cannot determine sort type");
}
int ret = 0;
if (term.field() == field) {
String termtext = term.text().trim();
try {
Integer.parseInt (termtext);
ret = SortField.INT;
} catch (NumberFormatException nfe1) {
try {
Long.parseLong(termtext);
ret = SortField.LONG;
} catch (NumberFormatException nfe2) {
try {
Float.parseFloat (termtext);
ret = SortField.FLOAT;
} catch (NumberFormatException nfe3) {
ret = SortField.STRING;
}
}
}
} else {
throw new RuntimeException("field \"" + field + "\" does not appear to be indexed");
}
return ret;
} finally {
enumerator.close();
}
}
}

View File

@ -1,98 +0,0 @@
package org.apache.lucene.search;
/**
* 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.
*/
import org.apache.lucene.util.PriorityQueue;
/** A {@link HitCollector} implementation that collects the top-scoring
* documents, returning them as a {@link TopDocs}. This is used by {@link
* IndexSearcher} to implement {@link TopDocs}-based search.
*
* <p>This may be extended, overriding the collect method to, e.g.,
* conditionally invoke <code>super()</code> in order to filter which
* documents are collected.
*
* @deprecated Please use {@link TopScoreDocCollector}
* instead, which has better performance.
**/
public class TopDocCollector extends HitCollector {
private ScoreDoc reusableSD;
/** The total number of hits the collector encountered. */
protected int totalHits;
/** The priority queue which holds the top-scoring documents. */
protected PriorityQueue hq;
/** Construct to collect a given number of hits.
* @param numHits the maximum number of hits to collect
*/
public TopDocCollector(int numHits) {
this(new HitQueue(numHits, false));
}
/** @deprecated use TopDocCollector(hq) instead. numHits is not used by this
* constructor. It will be removed in a future release.
*/
TopDocCollector(int numHits, PriorityQueue hq) {
this.hq = hq;
}
/** Constructor to collect the top-scoring documents by using the given PQ.
* @param hq the PQ to use by this instance.
*/
protected TopDocCollector(PriorityQueue hq) {
this.hq = hq;
}
// javadoc inherited
public void collect(int doc, float score) {
if (score > 0.0f) {
totalHits++;
if (reusableSD == null) {
reusableSD = new ScoreDoc(doc, score);
} else if (score >= reusableSD.score) {
// reusableSD holds the last "rejected" entry, so, if
// this new score is not better than that, there's no
// need to try inserting it
reusableSD.doc = doc;
reusableSD.score = score;
} else {
return;
}
reusableSD = (ScoreDoc) hq.insertWithOverflow(reusableSD);
}
}
/** The total number of documents that matched this query. */
public int getTotalHits() { return totalHits; }
/** The top-scoring hits. */
public TopDocs topDocs() {
ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
for (int i = hq.size()-1; i >= 0; i--) // put docs in array
scoreDocs[i] = (ScoreDoc)hq.pop();
float maxScore = (totalHits==0)
? Float.NEGATIVE_INFINITY
: scoreDocs[0].score;
return new TopDocs(totalHits, scoreDocs, maxScore);
}
}

View File

@ -1,77 +0,0 @@
package org.apache.lucene.search;
/**
* 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.
*/
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
/** A {@link HitCollector} implementation that collects the top-sorting
* documents, returning them as a {@link TopFieldDocs}. This is used by {@link
* IndexSearcher} to implement {@link TopFieldDocs}-based search.
*
* <p>This may be extended, overriding the collect method to, e.g.,
* conditionally invoke <code>super()</code> in order to filter which
* documents are collected.
*
* @deprecated Please use {@link TopFieldCollector} instead.
*/
public class TopFieldDocCollector extends TopDocCollector {
private FieldDoc reusableFD;
/** Construct to collect a given number of hits.
* @param reader the index to be searched
* @param sort the sort criteria
* @param numHits the maximum number of hits to collect
*/
public TopFieldDocCollector(IndexReader reader, Sort sort, int numHits)
throws IOException {
super(new FieldSortedHitQueue(reader, sort.fields, numHits));
}
// javadoc inherited
public void collect(int doc, float score) {
if (score > 0.0f) {
totalHits++;
if (reusableFD == null)
reusableFD = new FieldDoc(doc, score);
else {
// Whereas TopScoreDocCollector can skip this if the
// score is not competitive, we cannot because the
// comparators in the FieldSortedHitQueue.lessThan
// aren't in general congruent with "higher score
// wins"
reusableFD.score = score;
reusableFD.doc = doc;
}
reusableFD = (FieldDoc) hq.insertWithOverflow(reusableFD);
}
}
// javadoc inherited
public TopDocs topDocs() {
FieldSortedHitQueue fshq = (FieldSortedHitQueue)hq;
ScoreDoc[] scoreDocs = new ScoreDoc[fshq.size()];
for (int i = fshq.size()-1; i >= 0; i--) // put docs in array
scoreDocs[i] = fshq.fillFields ((FieldDoc) fshq.pop());
return new TopFieldDocs(totalHits, scoreDocs,
fshq.getFields(), fshq.getMaxScore());
}
}

View File

@ -104,10 +104,10 @@ implements Serializable {
public void testFieldSortCustomSearcher() throws Exception {
// log("Run testFieldSortCustomSearcher");
// define the sort criteria
Sort custSort = new Sort(new SortField[] {
new SortField("publicationDate_"),
Sort custSort = new Sort(
new SortField("publicationDate_", SortField.STRING),
SortField.FIELD_SCORE
});
);
Searcher searcher = new CustomSearcher (index, 2);
// search and check hits
matchHits(searcher, custSort);
@ -118,10 +118,10 @@ implements Serializable {
public void testFieldSortSingleSearcher() throws Exception {
// log("Run testFieldSortSingleSearcher");
// define the sort criteria
Sort custSort = new Sort(new SortField[] {
new SortField("publicationDate_"),
Sort custSort = new Sort(
new SortField("publicationDate_", SortField.STRING),
SortField.FIELD_SCORE
});
);
Searcher searcher = new MultiSearcher(new Searcher[] { new CustomSearcher(
index, 2) });
// search and check hits
@ -133,10 +133,10 @@ implements Serializable {
public void testFieldSortMultiCustomSearcher() throws Exception {
// log("Run testFieldSortMultiCustomSearcher");
// define the sort criteria
Sort custSort = new Sort(new SortField[] {
new SortField("publicationDate_"),
Sort custSort = new Sort(
new SortField("publicationDate_", SortField.STRING),
SortField.FIELD_SCORE
});
);
Searcher searcher =
new MultiSearcher(new Searchable[] {
new CustomSearcher (index, 0),

View File

@ -72,9 +72,7 @@ public class TestDateSort extends LuceneTestCase {
public void testReverseDateSort() throws Exception {
IndexSearcher searcher = new IndexSearcher(directory, true);
// Create a Sort object. reverse is set to true.
// problem occurs only with SortField.AUTO:
Sort sort = new Sort(new SortField(DATE_TIME_FIELD, SortField.AUTO, true));
Sort sort = new Sort(new SortField(DATE_TIME_FIELD, SortField.STRING, true));
QueryParser queryParser = new QueryParser(TEXT_FIELD, new WhitespaceAnalyzer());
Query query = queryParser.parse("Document");

View File

@ -66,10 +66,10 @@ public class TestElevationComparator extends LuceneTestCase {
newq.add(query, BooleanClause.Occur.SHOULD);
newq.add(getElevatedQuery(new String[] {"id", "a", "id", "x"}), BooleanClause.Occur.SHOULD);
Sort sort = new Sort(new SortField[]{
Sort sort = new Sort(
new SortField("id", new ElevationComparatorSource(priority), false),
new SortField(null, SortField.SCORE, reversed)
});
);
TopDocsCollector topCollector = TopFieldCollector.create(sort, 50, false, true, true, true);
searcher.search(newq, null, topCollector);

View File

@ -105,7 +105,7 @@ public class TestFilteredQuery extends LuceneTestCase {
assertEquals (1, hits[0].doc);
QueryUtils.check(filteredquery,searcher);
hits = searcher.search (filteredquery, null, 1000, new Sort("sorter")).scoreDocs;
hits = searcher.search (filteredquery, null, 1000, new Sort(new SortField("sorter", SortField.STRING))).scoreDocs;
assertEquals (1, hits.length);
assertEquals (1, hits[0].doc);

View File

@ -233,31 +233,31 @@ public class TestSort extends LuceneTestCase implements Serializable {
// test sorts where the type of field is specified
public void testTypedSort() throws Exception {
sort.setSort (new SortField[] { new SortField ("int", SortField.INT), SortField.FIELD_DOC });
sort.setSort (new SortField ("int", SortField.INT), SortField.FIELD_DOC );
assertMatches (full, queryX, sort, "IGAEC");
assertMatches (full, queryY, sort, "DHFJB");
sort.setSort (new SortField[] { new SortField ("float", SortField.FLOAT), SortField.FIELD_DOC });
sort.setSort (new SortField ("float", SortField.FLOAT), SortField.FIELD_DOC );
assertMatches (full, queryX, sort, "GCIEA");
assertMatches (full, queryY, sort, "DHJFB");
sort.setSort (new SortField[] { new SortField ("long", SortField.LONG), SortField.FIELD_DOC });
sort.setSort (new SortField ("long", SortField.LONG), SortField.FIELD_DOC );
assertMatches (full, queryX, sort, "EACGI");
assertMatches (full, queryY, sort, "FBJHD");
sort.setSort (new SortField[] { new SortField ("double", SortField.DOUBLE), SortField.FIELD_DOC });
sort.setSort (new SortField ("double", SortField.DOUBLE), SortField.FIELD_DOC );
assertMatches (full, queryX, sort, "AGICE");
assertMatches (full, queryY, sort, "DJHBF");
sort.setSort (new SortField[] { new SortField ("byte", SortField.BYTE), SortField.FIELD_DOC });
sort.setSort (new SortField ("byte", SortField.BYTE), SortField.FIELD_DOC );
assertMatches (full, queryX, sort, "CIGAE");
assertMatches (full, queryY, sort, "DHFBJ");
sort.setSort (new SortField[] { new SortField ("short", SortField.SHORT), SortField.FIELD_DOC });
sort.setSort (new SortField ("short", SortField.SHORT), SortField.FIELD_DOC );
assertMatches (full, queryX, sort, "IAGCE");
assertMatches (full, queryY, sort, "DFHBJ");
sort.setSort (new SortField[] { new SortField ("string", SortField.STRING), SortField.FIELD_DOC });
sort.setSort (new SortField ("string", SortField.STRING), SortField.FIELD_DOC );
assertMatches (full, queryX, sort, "AIGEC");
assertMatches (full, queryY, sort, "DJHFB");
}
@ -269,10 +269,10 @@ public class TestSort extends LuceneTestCase implements Serializable {
r = newRandom();
ScoreDoc[] result = null;
IndexSearcher searcher = getFullStrings();
sort.setSort(new SortField[] {
sort.setSort(
new SortField("string", SortField.STRING),
new SortField("string2", SortField.STRING, true),
SortField.FIELD_DOC });
SortField.FIELD_DOC );
result = searcher.search(new MatchAllDocsQuery(), null, 500, sort).scoreDocs;
@ -331,56 +331,56 @@ public class TestSort extends LuceneTestCase implements Serializable {
FieldCache fc = FieldCache.DEFAULT;
sort.setSort (new SortField[] { new SortField ("parser", new FieldCache.IntParser(){
sort.setSort (new SortField ("parser", new FieldCache.IntParser(){
public final int parseInt(final String val) {
return (val.charAt(0)-'A') * 123456;
}
}), SortField.FIELD_DOC });
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " IntParser");
fc.purgeAllCaches();
sort.setSort (new SortField[] { new SortField ("parser", new FieldCache.FloatParser(){
sort.setSort (new SortField ("parser", new FieldCache.FloatParser(){
public final float parseFloat(final String val) {
return (float) Math.sqrt( val.charAt(0) );
}
}), SortField.FIELD_DOC });
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " FloatParser");
fc.purgeAllCaches();
sort.setSort (new SortField[] { new SortField ("parser", new FieldCache.LongParser(){
sort.setSort (new SortField ("parser", new FieldCache.LongParser(){
public final long parseLong(final String val) {
return (val.charAt(0)-'A') * 1234567890L;
}
}), SortField.FIELD_DOC });
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " LongParser");
fc.purgeAllCaches();
sort.setSort (new SortField[] { new SortField ("parser", new FieldCache.DoubleParser(){
sort.setSort (new SortField ("parser", new FieldCache.DoubleParser(){
public final double parseDouble(final String val) {
return Math.pow( val.charAt(0), (val.charAt(0)-'A') );
}
}), SortField.FIELD_DOC });
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " DoubleParser");
fc.purgeAllCaches();
sort.setSort (new SortField[] { new SortField ("parser", new FieldCache.ByteParser(){
sort.setSort (new SortField ("parser", new FieldCache.ByteParser(){
public final byte parseByte(final String val) {
return (byte) (val.charAt(0)-'A');
}
}), SortField.FIELD_DOC });
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " ByteParser");
fc.purgeAllCaches();
sort.setSort (new SortField[] { new SortField ("parser", new FieldCache.ShortParser(){
sort.setSort (new SortField ("parser", new FieldCache.ShortParser(){
public final short parseShort(final String val) {
return (short) (val.charAt(0)-'A');
}
}), SortField.FIELD_DOC });
}), SortField.FIELD_DOC );
assertMatches (full, queryA, sort, "JIHGFEDCBA");
assertSaneFieldCaches(getName() + " ShortParser");
fc.purgeAllCaches();
@ -396,13 +396,13 @@ public class TestSort extends LuceneTestCase implements Serializable {
sort.setSort(SortField.FIELD_DOC);
assertMatches (empty, queryX, sort, "");
sort.setSort (new SortField[] { new SortField ("int", SortField.INT), SortField.FIELD_DOC });
sort.setSort (new SortField ("int", SortField.INT), SortField.FIELD_DOC );
assertMatches (empty, queryX, sort, "");
sort.setSort (new SortField[] { new SortField ("string", SortField.STRING, true), SortField.FIELD_DOC });
sort.setSort (new SortField ("string", SortField.STRING, true), SortField.FIELD_DOC );
assertMatches (empty, queryX, sort, "");
sort.setSort (new SortField[] { new SortField ("float", SortField.FLOAT), new SortField ("string", SortField.STRING) });
sort.setSort (new SortField ("float", SortField.FLOAT), new SortField ("string", SortField.STRING) );
assertMatches (empty, queryX, sort, "");
}
@ -452,28 +452,13 @@ public class TestSort extends LuceneTestCase implements Serializable {
// Test sorting w/ custom FieldComparator
public void testNewCustomFieldParserSort() throws Exception {
sort.setSort (new SortField[] { new SortField ("parser", new MyFieldComparatorSource())});
sort.setSort (new SortField ("parser", new MyFieldComparatorSource()));
assertMatches (full, queryA, sort, "JIHGFEDCBA");
}
// test sorts where the type of field is determined dynamically
public void testAutoSort() throws Exception {
sort.setSort("int");
assertMatches (full, queryX, sort, "IGAEC");
assertMatches (full, queryY, sort, "DHFJB");
sort.setSort("float");
assertMatches (full, queryX, sort, "GCIEA");
assertMatches (full, queryY, sort, "DHJFB");
sort.setSort("string");
assertMatches (full, queryX, sort, "AIGEC");
assertMatches (full, queryY, sort, "DJHFB");
}
// test sorts in reverse
public void testReverseSort() throws Exception {
sort.setSort (new SortField[] { new SortField (null, SortField.SCORE, true), SortField.FIELD_DOC });
sort.setSort (new SortField (null, SortField.SCORE, true), SortField.FIELD_DOC );
assertMatches (full, queryX, sort, "IEGCA");
assertMatches (full, queryY, sort, "JFHDB");
@ -481,25 +466,25 @@ public class TestSort extends LuceneTestCase implements Serializable {
assertMatches (full, queryX, sort, "IGECA");
assertMatches (full, queryY, sort, "JHFDB");
sort.setSort ("int", true);
sort.setSort (new SortField ("int", SortField.INT, true) );
assertMatches (full, queryX, sort, "CAEGI");
assertMatches (full, queryY, sort, "BJFHD");
sort.setSort ("float", true);
sort.setSort (new SortField ("float", SortField.FLOAT, true) );
assertMatches (full, queryX, sort, "AECIG");
assertMatches (full, queryY, sort, "BFJHD");
sort.setSort ("string", true);
sort.setSort (new SortField ("string", SortField.STRING, true) );
assertMatches (full, queryX, sort, "CEGIA");
assertMatches (full, queryY, sort, "BFHJD");
}
// test sorting when the sort field is empty (undefined) for some of the documents
public void testEmptyFieldSort() throws Exception {
sort.setSort ("string");
sort.setSort (new SortField ("string", SortField.STRING) );
assertMatches (full, queryF, sort, "ZJI");
sort.setSort ("string", true);
sort.setSort (new SortField ("string", SortField.STRING, true) );
assertMatches (full, queryF, sort, "IJZ");
sort.setSort (new SortField ("i18n", Locale.ENGLISH));
@ -508,84 +493,84 @@ public class TestSort extends LuceneTestCase implements Serializable {
sort.setSort (new SortField ("i18n", Locale.ENGLISH, true));
assertMatches (full, queryF, sort, "IJZ");
sort.setSort ("int");
sort.setSort (new SortField ("int", SortField.INT) );
assertMatches (full, queryF, sort, "IZJ");
sort.setSort ("int", true);
sort.setSort (new SortField ("int", SortField.INT, true) );
assertMatches (full, queryF, sort, "JZI");
sort.setSort ("float");
sort.setSort (new SortField ("float", SortField.FLOAT) );
assertMatches (full, queryF, sort, "ZJI");
// using a nonexisting field as first sort key shouldn't make a difference:
sort.setSort (new SortField[] { new SortField ("nosuchfield", SortField.STRING),
new SortField ("float") });
sort.setSort (new SortField ("nosuchfield", SortField.STRING),
new SortField ("float", SortField.FLOAT) );
assertMatches (full, queryF, sort, "ZJI");
sort.setSort ("float", true);
sort.setSort (new SortField ("float", SortField.FLOAT, true) );
assertMatches (full, queryF, sort, "IJZ");
// When a field is null for both documents, the next SortField should be used.
// Works for
sort.setSort (new SortField[] { new SortField ("int"),
sort.setSort (new SortField ("int", SortField.INT),
new SortField ("string", SortField.STRING),
new SortField ("float") });
new SortField ("float", SortField.FLOAT) );
assertMatches (full, queryG, sort, "ZWXY");
// Reverse the last criterium to make sure the test didn't pass by chance
sort.setSort (new SortField[] { new SortField ("int"),
sort.setSort (new SortField ("int", SortField.INT),
new SortField ("string", SortField.STRING),
new SortField ("float", true) });
new SortField ("float", SortField.FLOAT, true) );
assertMatches (full, queryG, sort, "ZYXW");
// Do the same for a MultiSearcher
Searcher multiSearcher=new MultiSearcher (new Searchable[] { full });
sort.setSort (new SortField[] { new SortField ("int"),
sort.setSort (new SortField ("int", SortField.INT),
new SortField ("string", SortField.STRING),
new SortField ("float") });
new SortField ("float", SortField.FLOAT) );
assertMatches (multiSearcher, queryG, sort, "ZWXY");
sort.setSort (new SortField[] { new SortField ("int"),
sort.setSort (new SortField ("int", SortField.INT),
new SortField ("string", SortField.STRING),
new SortField ("float", true) });
new SortField ("float", SortField.FLOAT, true) );
assertMatches (multiSearcher, queryG, sort, "ZYXW");
// Don't close the multiSearcher. it would close the full searcher too!
// Do the same for a ParallelMultiSearcher
Searcher parallelSearcher=new ParallelMultiSearcher (new Searchable[] { full });
sort.setSort (new SortField[] { new SortField ("int"),
sort.setSort (new SortField ("int", SortField.INT),
new SortField ("string", SortField.STRING),
new SortField ("float") });
new SortField ("float", SortField.FLOAT) );
assertMatches (parallelSearcher, queryG, sort, "ZWXY");
sort.setSort (new SortField[] { new SortField ("int"),
sort.setSort (new SortField ("int", SortField.INT),
new SortField ("string", SortField.STRING),
new SortField ("float", true) });
new SortField ("float", SortField.FLOAT, true) );
assertMatches (parallelSearcher, queryG, sort, "ZYXW");
// Don't close the parallelSearcher. it would close the full searcher too!
}
// test sorts using a series of fields
public void testSortCombos() throws Exception {
sort.setSort (new String[] {"int","float"});
sort.setSort (new SortField ("int", SortField.INT), new SortField ("float", SortField.FLOAT) );
assertMatches (full, queryX, sort, "IGEAC");
sort.setSort (new SortField[] { new SortField ("int", true), new SortField (null, SortField.DOC, true) });
sort.setSort (new SortField ("int", SortField.INT, true), new SortField (null, SortField.DOC, true) );
assertMatches (full, queryX, sort, "CEAGI");
sort.setSort (new String[] {"float","string"});
sort.setSort (new SortField ("float", SortField.FLOAT), new SortField ("string", SortField.STRING) );
assertMatches (full, queryX, sort, "GICEA");
}
// test using a Locale for sorting strings
public void testLocaleSort() throws Exception {
sort.setSort (new SortField[] { new SortField ("string", Locale.US) });
sort.setSort (new SortField ("string", Locale.US) );
assertMatches (full, queryX, sort, "AIGEC");
assertMatches (full, queryY, sort, "DJHFB");
sort.setSort (new SortField[] { new SortField ("string", Locale.US, true) });
sort.setSort (new SortField ("string", Locale.US, true) );
assertMatches (full, queryX, sort, "CEGIA");
assertMatches (full, queryY, sort, "BFHJD");
}
@ -667,7 +652,7 @@ public class TestSort extends LuceneTestCase implements Serializable {
assertSameValues (scoresA, getScores (full.search (queryA, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresA, getScores (multi.search (queryA, null, 1000, sort).scoreDocs, multi));
sort.setSort ("int");
sort.setSort (new SortField("int", SortField.INT));
assertSameValues (scoresX, getScores (full.search (queryX, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresX, getScores (multi.search (queryX, null, 1000, sort).scoreDocs, multi));
assertSameValues (scoresY, getScores (full.search (queryY, null, 1000, sort).scoreDocs, full));
@ -675,7 +660,7 @@ public class TestSort extends LuceneTestCase implements Serializable {
assertSameValues (scoresA, getScores (full.search (queryA, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresA, getScores (multi.search (queryA, null, 1000, sort).scoreDocs, multi));
sort.setSort ("float");
sort.setSort (new SortField("float", SortField.FLOAT));
assertSameValues (scoresX, getScores (full.search (queryX, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresX, getScores (multi.search (queryX, null, 1000, sort).scoreDocs, multi));
assertSameValues (scoresY, getScores (full.search (queryY, null, 1000, sort).scoreDocs, full));
@ -683,7 +668,7 @@ public class TestSort extends LuceneTestCase implements Serializable {
assertSameValues (scoresA, getScores (full.search (queryA, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresA, getScores (multi.search (queryA, null, 1000, sort).scoreDocs, multi));
sort.setSort ("string");
sort.setSort (new SortField("string", SortField.STRING));
assertSameValues (scoresX, getScores (full.search (queryX, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresX, getScores (multi.search (queryX, null, 1000, sort).scoreDocs, multi));
assertSameValues (scoresY, getScores (full.search (queryY, null, 1000, sort).scoreDocs, full));
@ -691,7 +676,7 @@ public class TestSort extends LuceneTestCase implements Serializable {
assertSameValues (scoresA, getScores (full.search (queryA, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresA, getScores (multi.search (queryA, null, 1000, sort).scoreDocs, multi));
sort.setSort (new String[] {"int","float"});
sort.setSort (new SortField("int", SortField.INT),new SortField("float", SortField.FLOAT));
assertSameValues (scoresX, getScores (full.search (queryX, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresX, getScores (multi.search (queryX, null, 1000, sort).scoreDocs, multi));
assertSameValues (scoresY, getScores (full.search (queryY, null, 1000, sort).scoreDocs, full));
@ -699,7 +684,7 @@ public class TestSort extends LuceneTestCase implements Serializable {
assertSameValues (scoresA, getScores (full.search (queryA, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresA, getScores (multi.search (queryA, null, 1000, sort).scoreDocs, multi));
sort.setSort (new SortField[] { new SortField ("int", true), new SortField (null, SortField.DOC, true) });
sort.setSort (new SortField ("int", SortField.INT, true), new SortField (null, SortField.DOC, true) );
assertSameValues (scoresX, getScores (full.search (queryX, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresX, getScores (multi.search (queryX, null, 1000, sort).scoreDocs, multi));
assertSameValues (scoresY, getScores (full.search (queryY, null, 1000, sort).scoreDocs, full));
@ -707,7 +692,7 @@ public class TestSort extends LuceneTestCase implements Serializable {
assertSameValues (scoresA, getScores (full.search (queryA, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresA, getScores (multi.search (queryA, null, 1000, sort).scoreDocs, multi));
sort.setSort (new String[] {"float","string"});
sort.setSort (new SortField("int", SortField.INT),new SortField("string", SortField.STRING));
assertSameValues (scoresX, getScores (full.search (queryX, null, 1000, sort).scoreDocs, full));
assertSameValues (scoresX, getScores (multi.search (queryX, null, 1000, sort).scoreDocs, multi));
assertSameValues (scoresY, getScores (full.search (queryY, null, 1000, sort).scoreDocs, full));
@ -909,52 +894,52 @@ public class TestSort extends LuceneTestCase implements Serializable {
expected = isFull ? "IDHFGJABEC" : "IDHFGJAEBC";
assertMatches(multi, queryA, sort, expected);
sort.setSort(new SortField[] {new SortField ("int", SortField.INT), SortField.FIELD_DOC});
sort.setSort(new SortField ("int", SortField.INT), SortField.FIELD_DOC);
expected = isFull ? "IDHFGJABEC" : "IDHFGJAEBC";
assertMatches(multi, queryA, sort, expected);
sort.setSort("int");
sort.setSort(new SortField("int", SortField.INT));
expected = isFull ? "IDHFGJABEC" : "IDHFGJAEBC";
assertMatches(multi, queryA, sort, expected);
sort.setSort(new SortField[] {new SortField ("float", SortField.FLOAT), SortField.FIELD_DOC});
sort.setSort(new SortField ("float", SortField.FLOAT), SortField.FIELD_DOC);
assertMatches(multi, queryA, sort, "GDHJCIEFAB");
sort.setSort("float");
sort.setSort(new SortField("float", SortField.FLOAT));
assertMatches(multi, queryA, sort, "GDHJCIEFAB");
sort.setSort("string");
sort.setSort(new SortField("string", SortField.STRING));
assertMatches(multi, queryA, sort, "DJAIHGFEBC");
sort.setSort("int", true);
sort.setSort(new SortField("int", SortField.INT, true));
expected = isFull ? "CABEJGFHDI" : "CAEBJGFHDI";
assertMatches(multi, queryA, sort, expected);
sort.setSort("float", true);
sort.setSort(new SortField("float", SortField.FLOAT, true));
assertMatches(multi, queryA, sort, "BAFECIJHDG");
sort.setSort("string", true);
sort.setSort(new SortField("string", SortField.STRING, true));
assertMatches(multi, queryA, sort, "CBEFGHIAJD");
sort.setSort(new String[] {"int","float"});
sort.setSort(new SortField("int", SortField.INT),new SortField("float", SortField.FLOAT));
assertMatches(multi, queryA, sort, "IDHFGJEABC");
sort.setSort(new String[] {"float","string"});
sort.setSort(new SortField("float", SortField.FLOAT),new SortField("string", SortField.STRING));
assertMatches(multi, queryA, sort, "GDHJICEFAB");
sort.setSort("int");
sort.setSort(new SortField ("int", SortField.INT));
assertMatches(multi, queryF, sort, "IZJ");
sort.setSort("int", true);
sort.setSort(new SortField ("int", SortField.INT, true));
assertMatches(multi, queryF, sort, "JZI");
sort.setSort("float");
sort.setSort(new SortField ("float", SortField.FLOAT));
assertMatches(multi, queryF, sort, "ZJI");
sort.setSort("string");
sort.setSort(new SortField ("string", SortField.STRING));
assertMatches(multi, queryF, sort, "ZJI");
sort.setSort("string", true);
sort.setSort(new SortField ("string", SortField.STRING, true));
assertMatches(multi, queryF, sort, "IJZ");
// up to this point, all of the searches should have "sane"
@ -963,13 +948,13 @@ public class TestSort extends LuceneTestCase implements Serializable {
// next we'll check Locale based (String[]) for 'string', so purge first
FieldCache.DEFAULT.purgeAllCaches();
sort.setSort(new SortField[] { new SortField ("string", Locale.US) });
sort.setSort(new SortField ("string", Locale.US) );
assertMatches(multi, queryA, sort, "DJAIHGFEBC");
sort.setSort(new SortField[] { new SortField ("string", Locale.US, true) });
sort.setSort(new SortField ("string", Locale.US, true) );
assertMatches(multi, queryA, sort, "CBEFGHIAJD");
sort.setSort(new SortField[] { new SortField ("string", Locale.UK) });
sort.setSort(new SortField ("string", Locale.UK) );
assertMatches(multi, queryA, sort, "DJAIHGFEBC");
assertSaneFieldCaches(getName() + " Locale.US + Locale.UK");

View File

@ -207,46 +207,34 @@ public class TestStressSort extends LuceneTestCase {
boolean reverse = 1 == r;
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField("byte", SortField.BYTE, reverse)});
sort.setSort(new SortField("byte", SortField.BYTE, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField("short", SortField.SHORT, reverse)});
sort.setSort(new SortField("short", SortField.SHORT, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField("int", SortField.INT, reverse)});
sort.setSort(new SortField("int", SortField.INT, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField("long", SortField.LONG, reverse)});
sort.setSort(new SortField("long", SortField.LONG, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField("float", SortField.FLOAT, reverse)});
sort.setSort(new SortField("float", SortField.FLOAT, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField("double", SortField.DOUBLE, reverse)});
sort.setSort(new SortField("double", SortField.DOUBLE, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField("string", SortField.STRING_VAL, reverse)});
sort.setSort(new SortField("string", SortField.STRING_VAL, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField("stringIdx", SortField.STRING, reverse)});
//sorts[sortCount++] = sort = new Sort();
//sort.setSort(new SortField[] {new SortField("string", SortField.STRING_ORD, reverse)});
//sorts[sortCount++] = sort = new Sort();
//sort.setSort(new SortField[] {new SortField("string", SortField.STRING_ORD_VAL, reverse)});
//sorts[sortCount++] = sort = new Sort();
//sort.setSort(new SortField[] {new SortField("string", SortField.STRING_ORD_VAL_DEM, reverse)});
//sorts[sortCount++] = sort = new Sort();
//sort.setSort(new SortField[] {new SortField("string", SortField.STRING_ORD_VAL_DEM2, reverse)});
sort.setSort(new SortField("stringIdx", SortField.STRING, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField(null, SortField.SCORE, reverse)});
sort.setSort(new SortField(null, SortField.SCORE, reverse));
sorts[sortCount++] = sort = new Sort();
sort.setSort(new SortField[] {new SortField(null, SortField.DOC, reverse)});
sort.setSort(new SortField(null, SortField.DOC, reverse));
}
Query[] queries = new Query[4];
@ -288,30 +276,8 @@ public class TestStressSort extends LuceneTestCase {
// Single field sort
sort = sort1;
} else {
sort = new Sort(new SortField[] {sort1.getSort()[0], sorts[s2].getSort()[0]});
sort = new Sort(sort1.getSort()[0], sorts[s2].getSort()[0]);
}
// Old
Sort oldSort = getOldSort(sort);
if (VERBOSE) {
System.out.println("query=" + query);
if (sx == 0) {
System.out.println(" single-segment index");
} else if (sx == 1) {
System.out.println(" few-segment index");
} else {
System.out.println(" many-segment index");
}
System.out.println(" numHit=" + queueSize);
System.out.println(" old=" + oldSort);
System.out.println(" new=" + sort);
}
TopDocs newHits = searcher.search(query, null, queueSize, sort);
TopDocs oldHits = searcher.search(query, null, queueSize, oldSort);
compare(oldHits, newHits);
}
}
}
@ -350,24 +316,6 @@ public class TestStressSort extends LuceneTestCase {
close();
}
private Sort getOldSort(Sort sort) {
SortField[] fields = sort.getSort();
SortField[] oldFields = new SortField[fields.length];
for(int i=0;i<fields.length;i++) {
int sortType;
if (fields[i].getField() != null && fields[i].getField().equals("string")) {
sortType = SortField.STRING;
} else {
sortType = fields[i].getType();
}
oldFields[i] = new SortField(fields[i].getField(),
sortType,
fields[i].getReverse());
oldFields[i].setUseLegacySearch(true);
}
return new Sort(oldFields);
}
private void compare(TopDocs oldHits, TopDocs newHits) {
assertEquals(oldHits.totalHits, newHits.totalHits);
assertEquals(oldHits.scoreDocs.length, newHits.scoreDocs.length);