blob: 29f88300c3695052a4de345bb297768afce4e4fa [file] [log] [blame]
Index: lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java (revision 1466751)
+++ lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java (working copy)
@@ -19,12 +19,16 @@
import org.apache.lucene.document.Field;
import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.SlowCompositeReaderWrapper;
import org.apache.lucene.index.FieldInvertState;
import org.apache.lucene.index.RandomIndexWriter;
@@ -32,6 +36,8 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.apache.lucene.search.similarities.Similarity;
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.store.Directory;
import java.text.DecimalFormat;
@@ -470,6 +476,39 @@
}
}
+ // LUCENE-4477 / LUCENE-4401:
+ public void testBooleanSpanQuery() throws Exception {
+ int hits = 0;
+ Directory directory = newDirectory();
+ Analyzer indexerAnalyzer = new MockAnalyzer(random());
+
+ IndexWriterConfig config = new IndexWriterConfig(TEST_VERSION_CURRENT, indexerAnalyzer);
+ IndexWriter writer = new IndexWriter(directory, config);
+ String FIELD = "content";
+ Document d = new Document();
+ d.add(new TextField(FIELD, "clockwork orange", Field.Store.YES));
+ writer.addDocument(d);
+ writer.close();
+
+ IndexReader indexReader = DirectoryReader.open(directory);
+ IndexSearcher searcher = newSearcher(indexReader);
+
+ DisjunctionMaxQuery query = new DisjunctionMaxQuery(1.0f);
+ SpanQuery sq1 = new SpanTermQuery(new Term(FIELD, "clockwork"));
+ SpanQuery sq2 = new SpanTermQuery(new Term(FIELD, "clckwork"));
+ query.add(sq1);
+ query.add(sq2);
+ TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
+ searcher.search(query, collector);
+ hits = collector.topDocs().scoreDocs.length;
+ for (ScoreDoc scoreDoc : collector.topDocs().scoreDocs){
+ System.out.println(scoreDoc.doc);
+ }
+ indexReader.close();
+ assertEquals(hits, 1);
+ directory.close();
+ }
+
/** macro */
protected Query tq(String f, String t) {
return new TermQuery(new Term(f, t));
Index: lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java (revision 1466751)
+++ lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java (working copy)
@@ -28,6 +28,7 @@
/* Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. */
private final float tieBreakerMultiplier;
private int doc = -1;
+ private int freq = -1;
/* Used when scoring currently matching doc. */
private float scoreSum;
@@ -55,8 +56,8 @@
@Override
public int nextDoc() throws IOException {
- if (numScorers == 0) return doc = NO_MORE_DOCS;
- while (subScorers[0].docID() == doc) {
+ assert doc != NO_MORE_DOCS;
+ while(true) {
if (subScorers[0].nextDoc() != NO_MORE_DOCS) {
heapAdjust(0);
} else {
@@ -65,9 +66,11 @@
return doc = NO_MORE_DOCS;
}
}
+ if (subScorers[0].docID() != doc) {
+ afterNext();
+ return doc;
+ }
}
-
- return doc = subScorers[0].docID();
}
@Override
@@ -80,47 +83,40 @@
*/
@Override
public float score() throws IOException {
- int doc = subScorers[0].docID();
- scoreSum = scoreMax = subScorers[0].score();
- int size = numScorers;
- scoreAll(1, size, doc);
- scoreAll(2, size, doc);
return scoreMax + (scoreSum - scoreMax) * tieBreakerMultiplier;
}
+
+ private void afterNext() throws IOException {
+ doc = subScorers[0].docID();
+ if (doc != NO_MORE_DOCS) {
+ scoreSum = scoreMax = subScorers[0].score();
+ freq = 1;
+ scoreAll(1);
+ scoreAll(2);
+ }
+ }
// Recursively iterate all subScorers that generated last doc computing sum and max
- private void scoreAll(int root, int size, int doc) throws IOException {
- if (root < size && subScorers[root].docID() == doc) {
+ private void scoreAll(int root) throws IOException {
+ if (root < numScorers && subScorers[root].docID() == doc) {
float sub = subScorers[root].score();
+ freq++;
scoreSum += sub;
scoreMax = Math.max(scoreMax, sub);
- scoreAll((root<<1)+1, size, doc);
- scoreAll((root<<1)+2, size, doc);
+ scoreAll((root<<1)+1);
+ scoreAll((root<<1)+2);
}
}
@Override
public int freq() throws IOException {
- int doc = subScorers[0].docID();
- int size = numScorers;
- return 1 + freq(1, size, doc) + freq(2, size, doc);
- }
-
- // Recursively iterate all subScorers that generated last doc computing sum and max
- private int freq(int root, int size, int doc) throws IOException {
- int freq = 0;
- if (root < size && subScorers[root].docID() == doc) {
- freq++;
- freq += freq((root<<1)+1, size, doc);
- freq += freq((root<<1)+2, size, doc);
- }
return freq;
}
@Override
public int advance(int target) throws IOException {
- if (numScorers == 0) return doc = NO_MORE_DOCS;
- while (subScorers[0].docID() < target) {
+ assert doc != NO_MORE_DOCS;
+ while(true) {
if (subScorers[0].advance(target) != NO_MORE_DOCS) {
heapAdjust(0);
} else {
@@ -129,7 +125,10 @@
return doc = NO_MORE_DOCS;
}
}
+ if (subScorers[0].docID() >= target) {
+ afterNext();
+ return doc;
+ }
}
- return doc = subScorers[0].docID();
}
}