You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2015/06/19 21:21:50 UTC
svn commit: r1686486 - in /lucene/dev/branches/branch_5x: ./ lucene/
lucene/CHANGES.txt lucene/join/
lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java
lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
Author: jpountz
Date: Fri Jun 19 19:21:50 2015
New Revision: 1686486
URL: http://svn.apache.org/r1686486
Log:
LUCENE-6593: Fix ToChildBlockJoinQuery's scorer to not refuse to advance to a document that belongs to the parent space.
Modified:
lucene/dev/branches/branch_5x/ (props changed)
lucene/dev/branches/branch_5x/lucene/ (props changed)
lucene/dev/branches/branch_5x/lucene/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_5x/lucene/join/ (props changed)
lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java
lucene/dev/branches/branch_5x/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
Modified: lucene/dev/branches/branch_5x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/CHANGES.txt?rev=1686486&r1=1686485&r2=1686486&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_5x/lucene/CHANGES.txt Fri Jun 19 19:21:50 2015
@@ -119,6 +119,9 @@ Bug fixes
as workaround); fix output of tests to use same format. (Uwe Schindler,
Ramkumar Aiyengar)
+* LUCENE-6593: Fixed ToChildBlockJoinQuery's scorer to not refuse to advance
+ to a document that belongs to the parent space. (Adrien Grand)
+
Changes in Runtime Behavior
* LUCENE-6501: The subreader structure in ParallelCompositeReader
Modified: lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java?rev=1686486&r1=1686485&r2=1686486&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java (original)
+++ lucene/dev/branches/branch_5x/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java Fri Jun 19 19:21:50 2015
@@ -159,7 +159,7 @@ public class ToChildBlockJoinQuery exten
private int parentFreq = 1;
private int childDoc = -1;
- private int parentDoc;
+ private int parentDoc = 0;
public ToChildBlockJoinScorer(Weight weight, Scorer parentScorer, BitSet parentBits, boolean doScores, Bits acceptDocs) {
super(weight);
@@ -268,40 +268,41 @@ public class ToChildBlockJoinQuery exten
@Override
public int advance(int childTarget) throws IOException {
-
- //System.out.println("Q.advance childTarget=" + childTarget);
- if (childTarget == NO_MORE_DOCS) {
- //System.out.println(" END");
- return childDoc = parentDoc = NO_MORE_DOCS;
- }
-
- if (parentBits.get(childTarget)) {
- throw new IllegalStateException(ILLEGAL_ADVANCE_ON_PARENT + childTarget);
- }
-
- assert childDoc == -1 || childTarget != parentDoc: "childTarget=" + childTarget;
- if (childDoc == -1 || childTarget > parentDoc) {
- // Advance to new parent:
- parentDoc = parentScorer.advance(childTarget);
+ if (childTarget >= parentDoc) {
+ if (childTarget == NO_MORE_DOCS) {
+ return childDoc = parentDoc = NO_MORE_DOCS;
+ }
+ parentDoc = parentScorer.advance(childTarget + 1);
validateParentDoc();
- //System.out.println(" advance to parentDoc=" + parentDoc);
- assert parentDoc > childTarget;
+
if (parentDoc == NO_MORE_DOCS) {
- //System.out.println(" END");
return childDoc = NO_MORE_DOCS;
}
+
+ // scan to the first parent that has children
+ while (true) {
+ final int firstChild = parentBits.prevSetBit(parentDoc-1) + 1;
+ if (firstChild != parentDoc) {
+ // this parent has children
+ childTarget = Math.max(childTarget, firstChild);
+ break;
+ }
+ // parent with no children, move to the next one
+ parentDoc = parentScorer.nextDoc();
+ validateParentDoc();
+ if (parentDoc == NO_MORE_DOCS) {
+ return childDoc = NO_MORE_DOCS;
+ }
+ }
+
if (doScores) {
parentScore = parentScorer.score();
parentFreq = parentScorer.freq();
}
- final int firstChild = parentBits.prevSetBit(parentDoc-1);
- //System.out.println(" firstChild=" + firstChild);
- childTarget = Math.max(childTarget, firstChild);
}
assert childTarget < parentDoc;
-
- // Advance within children of current parent:
+ assert !parentBits.get(childTarget);
childDoc = childTarget;
//System.out.println(" " + childDoc);
if (acceptDocs != null && !acceptDocs.get(childDoc)) {
Modified: lucene/dev/branches/branch_5x/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java?rev=1686486&r1=1686485&r2=1686486&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java (original)
+++ lucene/dev/branches/branch_5x/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java Fri Jun 19 19:21:50 2015
@@ -17,13 +17,22 @@ package org.apache.lucene.search.join;
* limitations under the License.
*/
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedDocValuesField;
import org.apache.lucene.document.StoredField;
+import org.apache.lucene.document.StringField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
@@ -36,8 +45,28 @@ import org.apache.lucene.index.PostingsE
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.index.Term;
-import org.apache.lucene.search.*;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.FieldDoc;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.FilteredQuery;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.MultiTermQuery;
+import org.apache.lucene.search.NumericRangeQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryUtils;
+import org.apache.lucene.search.QueryWrapperFilter;
+import org.apache.lucene.search.RandomApproximationQuery;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.search.Weight;
import org.apache.lucene.search.grouping.GroupDocs;
import org.apache.lucene.search.grouping.TopGroups;
import org.apache.lucene.store.Directory;
@@ -49,13 +78,6 @@ import org.apache.lucene.util.LuceneTest
import org.apache.lucene.util.NumericUtils;
import org.apache.lucene.util.TestUtil;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
public class TestBlockJoin extends LuceneTestCase {
// One resume...
@@ -1516,4 +1538,45 @@ public class TestBlockJoin extends Lucen
r.close();
dir.close();
}
+
+ public void testIntersectionWithRandomApproximation() throws IOException {
+ final Directory dir = newDirectory();
+ final RandomIndexWriter w = new RandomIndexWriter(random(), dir);
+
+ final int numBlocks = atLeast(100);
+ for (int i = 0; i < numBlocks; ++i) {
+ List<Document> docs = new ArrayList<>();
+ final int numChildren = random().nextInt(3);
+ for (int j = 0; j < numChildren; ++j) {
+ Document child = new Document();
+ child.add(new StringField("foo_child", random().nextBoolean() ? "bar" : "baz", Store.NO));
+ docs.add(child);
+ }
+ Document parent = new Document();
+ parent.add(new StringField("parent", "true", Store.NO));
+ parent.add(new StringField("foo_parent", random().nextBoolean() ? "bar" : "baz", Store.NO));
+ docs.add(parent);
+ w.addDocuments(docs);
+ }
+ final IndexReader reader = w.getReader();
+ final IndexSearcher searcher = newSearcher(reader);
+ searcher.setQueryCache(null); // to have real advance() calls
+
+ final BitDocIdSetFilter parentsFilter = new BitDocIdSetCachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("parent", "true"))));
+ final Query toChild = new ToChildBlockJoinQuery(new TermQuery(new Term("foo_parent", "bar")), parentsFilter);
+ final Query childQuery = new TermQuery(new Term("foo_child", "baz"));
+
+ BooleanQuery bq1 = new BooleanQuery();
+ bq1.add(toChild, Occur.MUST);
+ bq1.add(childQuery, Occur.MUST);
+ BooleanQuery bq2 = new BooleanQuery();
+ bq2.add(toChild, Occur.MUST);
+ bq2.add(new RandomApproximationQuery(childQuery, random()), Occur.MUST);
+
+ assertEquals(searcher.count(bq1), searcher.count(bq2));
+
+ searcher.getIndexReader().close();
+ w.close();
+ dir.close();
+ }
}