diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSort.java b/lucene/core/src/test/org/apache/lucene/search/TestSort.java index 5ad87e889ad..2cfed756cec 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestSort.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestSort.java @@ -20,11 +20,6 @@ package org.apache.lucene.search; import java.io.IOException; import java.util.ArrayList; import java.util.BitSet; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Random; -import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -44,7 +39,6 @@ import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.FieldInfo.DocValuesType; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.MultiReader; import org.apache.lucene.index.RandomIndexWriter; @@ -53,13 +47,10 @@ import org.apache.lucene.index.StoredDocument; import org.apache.lucene.index.Term; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; -import org.apache.lucene.search.BooleanClause.Occur; -import org.apache.lucene.search.FieldValueHitQueue.Entry; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.DocIdBitSet; -import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.NamedThreadFactory; import org.apache.lucene.util._TestUtil; @@ -939,219 +930,6 @@ public class TestSort extends LuceneTestCase { assertEquals(docs1.scoreDocs[0].score, docs2.scoreDocs[0].score, 1e-6); } - public void testSortWithoutFillFields() throws Exception { - - // There was previously a bug in TopFieldCollector when fillFields was set - // to false - the same doc and score was set in ScoreDoc[] array. This test - // asserts that if fillFields is false, the documents are set properly. It - // does not use Searcher's default search methods (with Sort) since all set - // fillFields to true. - Sort[] sort = new Sort[] { new Sort(SortField.FIELD_DOC), new Sort() }; - for(int i = 0; i < sort.length; i++) { - Query q = new MatchAllDocsQuery(); - TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, false, - false, false, true); - - full.search(q, tdc); - - ScoreDoc[] sd = tdc.topDocs().scoreDocs; - for(int j = 1; j < sd.length; j++) { - assertTrue(sd[j].doc != sd[j - 1].doc); - } - - } - } - - public void testSortWithoutScoreTracking() throws Exception { - - // Two Sort criteria to instantiate the multi/single comparators. - Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; - for(int i = 0; i < sort.length; i++) { - Query q = new MatchAllDocsQuery(); - TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, false, - false, true); - - full.search(q, tdc); - - TopDocs td = tdc.topDocs(); - ScoreDoc[] sd = td.scoreDocs; - for(int j = 0; j < sd.length; j++) { - assertTrue(Float.isNaN(sd[j].score)); - } - assertTrue(Float.isNaN(td.getMaxScore())); - } - } - - public void testSortWithScoreNoMaxScoreTracking() throws Exception { - - // Two Sort criteria to instantiate the multi/single comparators. - Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; - for(int i = 0; i < sort.length; i++) { - Query q = new MatchAllDocsQuery(); - TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, true, - false, true); - - full.search(q, tdc); - - TopDocs td = tdc.topDocs(); - ScoreDoc[] sd = td.scoreDocs; - for(int j = 0; j < sd.length; j++) { - assertTrue(!Float.isNaN(sd[j].score)); - } - assertTrue(Float.isNaN(td.getMaxScore())); - } - } - - // MultiComparatorScoringNoMaxScoreCollector - public void testSortWithScoreNoMaxScoreTrackingMulti() throws Exception { - - // Two Sort criteria to instantiate the multi/single comparators. - Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC, SortField.FIELD_SCORE) }; - for(int i = 0; i < sort.length; i++) { - Query q = new MatchAllDocsQuery(); - TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, true, - false, true); - - full.search(q, tdc); - - TopDocs td = tdc.topDocs(); - ScoreDoc[] sd = td.scoreDocs; - for(int j = 0; j < sd.length; j++) { - assertTrue(!Float.isNaN(sd[j].score)); - } - assertTrue(Float.isNaN(td.getMaxScore())); - } - } - - public void testSortWithScoreAndMaxScoreTracking() throws Exception { - - // Two Sort criteria to instantiate the multi/single comparators. - Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; - for(int i = 0; i < sort.length; i++) { - Query q = new MatchAllDocsQuery(); - TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, true, - true, true); - - full.search(q, tdc); - - TopDocs td = tdc.topDocs(); - ScoreDoc[] sd = td.scoreDocs; - for(int j = 0; j < sd.length; j++) { - assertTrue(!Float.isNaN(sd[j].score)); - } - assertTrue(!Float.isNaN(td.getMaxScore())); - } - } - - public void testOutOfOrderDocsScoringSort() throws Exception { - - // Two Sort criteria to instantiate the multi/single comparators. - Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; - boolean[][] tfcOptions = new boolean[][] { - new boolean[] { false, false, false }, - new boolean[] { false, false, true }, - new boolean[] { false, true, false }, - new boolean[] { false, true, true }, - new boolean[] { true, false, false }, - new boolean[] { true, false, true }, - new boolean[] { true, true, false }, - new boolean[] { true, true, true }, - }; - String[] actualTFCClasses = new String[] { - "OutOfOrderOneComparatorNonScoringCollector", - "OutOfOrderOneComparatorScoringMaxScoreCollector", - "OutOfOrderOneComparatorScoringNoMaxScoreCollector", - "OutOfOrderOneComparatorScoringMaxScoreCollector", - "OutOfOrderOneComparatorNonScoringCollector", - "OutOfOrderOneComparatorScoringMaxScoreCollector", - "OutOfOrderOneComparatorScoringNoMaxScoreCollector", - "OutOfOrderOneComparatorScoringMaxScoreCollector" - }; - - BooleanQuery bq = new BooleanQuery(); - // Add a Query with SHOULD, since bw.scorer() returns BooleanScorer2 - // which delegates to BS if there are no mandatory clauses. - bq.add(new MatchAllDocsQuery(), Occur.SHOULD); - // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return - // the clause instead of BQ. - bq.setMinimumNumberShouldMatch(1); - for(int i = 0; i < sort.length; i++) { - for(int j = 0; j < tfcOptions.length; j++) { - TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, - tfcOptions[j][0], tfcOptions[j][1], tfcOptions[j][2], false); - - assertTrue(tdc.getClass().getName().endsWith("$"+actualTFCClasses[j])); - - full.search(bq, tdc); - - TopDocs td = tdc.topDocs(); - ScoreDoc[] sd = td.scoreDocs; - assertEquals(10, sd.length); - } - } - } - - // OutOfOrderMulti*Collector - public void testOutOfOrderDocsScoringSortMulti() throws Exception { - - // Two Sort criteria to instantiate the multi/single comparators. - Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC, SortField.FIELD_SCORE) }; - boolean[][] tfcOptions = new boolean[][] { - new boolean[] { false, false, false }, - new boolean[] { false, false, true }, - new boolean[] { false, true, false }, - new boolean[] { false, true, true }, - new boolean[] { true, false, false }, - new boolean[] { true, false, true }, - new boolean[] { true, true, false }, - new boolean[] { true, true, true }, - }; - String[] actualTFCClasses = new String[] { - "OutOfOrderMultiComparatorNonScoringCollector", - "OutOfOrderMultiComparatorScoringMaxScoreCollector", - "OutOfOrderMultiComparatorScoringNoMaxScoreCollector", - "OutOfOrderMultiComparatorScoringMaxScoreCollector", - "OutOfOrderMultiComparatorNonScoringCollector", - "OutOfOrderMultiComparatorScoringMaxScoreCollector", - "OutOfOrderMultiComparatorScoringNoMaxScoreCollector", - "OutOfOrderMultiComparatorScoringMaxScoreCollector" - }; - - BooleanQuery bq = new BooleanQuery(); - // Add a Query with SHOULD, since bw.scorer() returns BooleanScorer2 - // which delegates to BS if there are no mandatory clauses. - bq.add(new MatchAllDocsQuery(), Occur.SHOULD); - // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return - // the clause instead of BQ. - bq.setMinimumNumberShouldMatch(1); - for(int i = 0; i < sort.length; i++) { - for(int j = 0; j < tfcOptions.length; j++) { - TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, - tfcOptions[j][0], tfcOptions[j][1], tfcOptions[j][2], false); - - assertTrue(tdc.getClass().getName().endsWith("$"+actualTFCClasses[j])); - - full.search(bq, tdc); - - TopDocs td = tdc.topDocs(); - ScoreDoc[] sd = td.scoreDocs; - assertEquals(10, sd.length); - } - } - } - - public void testSortWithScoreAndMaxScoreTrackingNoResults() throws Exception { - - // Two Sort criteria to instantiate the multi/single comparators. - Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; - for(int i = 0; i < sort.length; i++) { - TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, true, true, true); - TopDocs td = tdc.topDocs(); - assertEquals(0, td.totalHits); - assertTrue(Float.isNaN(td.getMaxScore())); - } - } - // runs a variety of sorts useful for multisearchers private void runMultiSorts(IndexSearcher multi, boolean isFull) throws Exception { sort.setSort(SortField.FIELD_DOC); diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java new file mode 100644 index 00000000000..0492c2dd59d --- /dev/null +++ b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java @@ -0,0 +1,267 @@ +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.document.Document; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.RandomIndexWriter; +import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.search.FieldValueHitQueue.Entry; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.LuceneTestCase; + +public class TestTopFieldCollector extends LuceneTestCase { + private IndexSearcher is; + private IndexReader ir; + private Directory dir; + + @Override + public void setUp() throws Exception { + super.setUp(); + dir = newDirectory(); + RandomIndexWriter iw = new RandomIndexWriter(random(), dir); + int numDocs = atLeast(100); + for (int i = 0; i < numDocs; i++) { + Document doc = new Document(); + iw.addDocument(doc); + } + ir = iw.getReader(); + iw.close(); + is = newSearcher(ir); + } + + @Override + public void tearDown() throws Exception { + ir.close(); + dir.close(); + super.tearDown(); + } + + public void testSortWithoutFillFields() throws Exception { + + // There was previously a bug in TopFieldCollector when fillFields was set + // to false - the same doc and score was set in ScoreDoc[] array. This test + // asserts that if fillFields is false, the documents are set properly. It + // does not use Searcher's default search methods (with Sort) since all set + // fillFields to true. + Sort[] sort = new Sort[] { new Sort(SortField.FIELD_DOC), new Sort() }; + for(int i = 0; i < sort.length; i++) { + Query q = new MatchAllDocsQuery(); + TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, false, + false, false, true); + + is.search(q, tdc); + + ScoreDoc[] sd = tdc.topDocs().scoreDocs; + for(int j = 1; j < sd.length; j++) { + assertTrue(sd[j].doc != sd[j - 1].doc); + } + + } + } + + public void testSortWithoutScoreTracking() throws Exception { + + // Two Sort criteria to instantiate the multi/single comparators. + Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; + for(int i = 0; i < sort.length; i++) { + Query q = new MatchAllDocsQuery(); + TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, false, + false, true); + + is.search(q, tdc); + + TopDocs td = tdc.topDocs(); + ScoreDoc[] sd = td.scoreDocs; + for(int j = 0; j < sd.length; j++) { + assertTrue(Float.isNaN(sd[j].score)); + } + assertTrue(Float.isNaN(td.getMaxScore())); + } + } + + public void testSortWithScoreNoMaxScoreTracking() throws Exception { + + // Two Sort criteria to instantiate the multi/single comparators. + Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; + for(int i = 0; i < sort.length; i++) { + Query q = new MatchAllDocsQuery(); + TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, true, + false, true); + + is.search(q, tdc); + + TopDocs td = tdc.topDocs(); + ScoreDoc[] sd = td.scoreDocs; + for(int j = 0; j < sd.length; j++) { + assertTrue(!Float.isNaN(sd[j].score)); + } + assertTrue(Float.isNaN(td.getMaxScore())); + } + } + + // MultiComparatorScoringNoMaxScoreCollector + public void testSortWithScoreNoMaxScoreTrackingMulti() throws Exception { + + // Two Sort criteria to instantiate the multi/single comparators. + Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC, SortField.FIELD_SCORE) }; + for(int i = 0; i < sort.length; i++) { + Query q = new MatchAllDocsQuery(); + TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, true, + false, true); + + is.search(q, tdc); + + TopDocs td = tdc.topDocs(); + ScoreDoc[] sd = td.scoreDocs; + for(int j = 0; j < sd.length; j++) { + assertTrue(!Float.isNaN(sd[j].score)); + } + assertTrue(Float.isNaN(td.getMaxScore())); + } + } + + public void testSortWithScoreAndMaxScoreTracking() throws Exception { + + // Two Sort criteria to instantiate the multi/single comparators. + Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; + for(int i = 0; i < sort.length; i++) { + Query q = new MatchAllDocsQuery(); + TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, true, + true, true); + + is.search(q, tdc); + + TopDocs td = tdc.topDocs(); + ScoreDoc[] sd = td.scoreDocs; + for(int j = 0; j < sd.length; j++) { + assertTrue(!Float.isNaN(sd[j].score)); + } + assertTrue(!Float.isNaN(td.getMaxScore())); + } + } + + public void testOutOfOrderDocsScoringSort() throws Exception { + + // Two Sort criteria to instantiate the multi/single comparators. + Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; + boolean[][] tfcOptions = new boolean[][] { + new boolean[] { false, false, false }, + new boolean[] { false, false, true }, + new boolean[] { false, true, false }, + new boolean[] { false, true, true }, + new boolean[] { true, false, false }, + new boolean[] { true, false, true }, + new boolean[] { true, true, false }, + new boolean[] { true, true, true }, + }; + String[] actualTFCClasses = new String[] { + "OutOfOrderOneComparatorNonScoringCollector", + "OutOfOrderOneComparatorScoringMaxScoreCollector", + "OutOfOrderOneComparatorScoringNoMaxScoreCollector", + "OutOfOrderOneComparatorScoringMaxScoreCollector", + "OutOfOrderOneComparatorNonScoringCollector", + "OutOfOrderOneComparatorScoringMaxScoreCollector", + "OutOfOrderOneComparatorScoringNoMaxScoreCollector", + "OutOfOrderOneComparatorScoringMaxScoreCollector" + }; + + BooleanQuery bq = new BooleanQuery(); + // Add a Query with SHOULD, since bw.scorer() returns BooleanScorer2 + // which delegates to BS if there are no mandatory clauses. + bq.add(new MatchAllDocsQuery(), Occur.SHOULD); + // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return + // the clause instead of BQ. + bq.setMinimumNumberShouldMatch(1); + for(int i = 0; i < sort.length; i++) { + for(int j = 0; j < tfcOptions.length; j++) { + TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, + tfcOptions[j][0], tfcOptions[j][1], tfcOptions[j][2], false); + + assertTrue(tdc.getClass().getName().endsWith("$"+actualTFCClasses[j])); + + is.search(bq, tdc); + + TopDocs td = tdc.topDocs(); + ScoreDoc[] sd = td.scoreDocs; + assertEquals(10, sd.length); + } + } + } + + // OutOfOrderMulti*Collector + public void testOutOfOrderDocsScoringSortMulti() throws Exception { + + // Two Sort criteria to instantiate the multi/single comparators. + Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC, SortField.FIELD_SCORE) }; + boolean[][] tfcOptions = new boolean[][] { + new boolean[] { false, false, false }, + new boolean[] { false, false, true }, + new boolean[] { false, true, false }, + new boolean[] { false, true, true }, + new boolean[] { true, false, false }, + new boolean[] { true, false, true }, + new boolean[] { true, true, false }, + new boolean[] { true, true, true }, + }; + String[] actualTFCClasses = new String[] { + "OutOfOrderMultiComparatorNonScoringCollector", + "OutOfOrderMultiComparatorScoringMaxScoreCollector", + "OutOfOrderMultiComparatorScoringNoMaxScoreCollector", + "OutOfOrderMultiComparatorScoringMaxScoreCollector", + "OutOfOrderMultiComparatorNonScoringCollector", + "OutOfOrderMultiComparatorScoringMaxScoreCollector", + "OutOfOrderMultiComparatorScoringNoMaxScoreCollector", + "OutOfOrderMultiComparatorScoringMaxScoreCollector" + }; + + BooleanQuery bq = new BooleanQuery(); + // Add a Query with SHOULD, since bw.scorer() returns BooleanScorer2 + // which delegates to BS if there are no mandatory clauses. + bq.add(new MatchAllDocsQuery(), Occur.SHOULD); + // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return + // the clause instead of BQ. + bq.setMinimumNumberShouldMatch(1); + for(int i = 0; i < sort.length; i++) { + for(int j = 0; j < tfcOptions.length; j++) { + TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, + tfcOptions[j][0], tfcOptions[j][1], tfcOptions[j][2], false); + + assertTrue(tdc.getClass().getName().endsWith("$"+actualTFCClasses[j])); + + is.search(bq, tdc); + + TopDocs td = tdc.topDocs(); + ScoreDoc[] sd = td.scoreDocs; + assertEquals(10, sd.length); + } + } + } + + public void testSortWithScoreAndMaxScoreTrackingNoResults() throws Exception { + + // Two Sort criteria to instantiate the multi/single comparators. + Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() }; + for(int i = 0; i < sort.length; i++) { + TopDocsCollector tdc = TopFieldCollector.create(sort[i], 10, true, true, true, true); + TopDocs td = tdc.topDocs(); + assertEquals(0, td.totalHits); + assertTrue(Float.isNaN(td.getMaxScore())); + } + } +}