| diff --git a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java |
| index f6985e2..b67dbd8 100644 |
| --- a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java |
| +++ b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java |
| @@ -60,10 +60,6 @@ import org.apache.lucene.util.FixedBitSet; |
| * <p>See {@link ToChildBlockJoinQuery} if you need to join |
| * in the reverse order. |
| * |
| - * <p>The child documents must be orthogonal to the parent |
| - * documents: the wrapped child query must never |
| - * return a parent document.</p> |
| - * |
| * If you'd like to retrieve {@link TopGroups} for the |
| * resulting query, use the {@link ToParentBlockJoinCollector}. |
| * Note that this is not necessary, ie, if you simply want |
| @@ -280,12 +276,6 @@ public class ToParentBlockJoinQuery extends Query { |
| |
| parentDoc = parentBits.nextSetBit(nextChildDoc); |
| |
| - // Parent & child docs are supposed to be |
| - // orthogonal: |
| - if (nextChildDoc == parentDoc) { |
| - throw new IllegalStateException("child query must only match non-parent docs, but parent docID=" + nextChildDoc + " matched childScorer=" + childScorer.getClass()); |
| - } |
| - |
| //System.out.println(" parentDoc=" + parentDoc); |
| assert parentDoc != -1; |
| |
| @@ -295,13 +285,7 @@ public class ToParentBlockJoinQuery extends Query { |
| // we hit a new parent doc: |
| do { |
| nextChildDoc = childScorer.nextDoc(); |
| - } while (nextChildDoc < parentDoc); |
| - |
| - // Parent & child docs are supposed to be |
| - // orthogonal: |
| - if (nextChildDoc == parentDoc) { |
| - throw new IllegalStateException("child query must only match non-parent docs, but parent docID=" + nextChildDoc + " matched childScorer=" + childScorer.getClass()); |
| - } |
| + } while (nextChildDoc <= parentDoc); |
| |
| continue; |
| } |
| @@ -336,13 +320,7 @@ public class ToParentBlockJoinQuery extends Query { |
| } |
| childDocUpto++; |
| nextChildDoc = childScorer.nextDoc(); |
| - } while (nextChildDoc < parentDoc); |
| - |
| - // Parent & child docs are supposed to be |
| - // orthogonal: |
| - if (nextChildDoc == parentDoc) { |
| - throw new IllegalStateException("child query must only match non-parent docs, but parent docID=" + nextChildDoc + " matched childScorer=" + childScorer.getClass()); |
| - } |
| + } while (nextChildDoc <= parentDoc); |
| |
| switch(scoreMode) { |
| case Avg: |
| @@ -400,18 +378,13 @@ public class ToParentBlockJoinQuery extends Query { |
| |
| //System.out.println(" rolled back to prevParentDoc=" + prevParentDoc + " vs parentDoc=" + parentDoc); |
| assert prevParentDoc >= parentDoc; |
| - if (prevParentDoc > nextChildDoc) { |
| - nextChildDoc = childScorer.advance(prevParentDoc); |
| + if (prevParentDoc >= nextChildDoc) { |
| + nextChildDoc = childScorer.advance(prevParentDoc + 1); |
| // System.out.println(" childScorer advanced to child docID=" + nextChildDoc); |
| //} else { |
| //System.out.println(" skip childScorer advance"); |
| } |
| |
| - // Parent & child docs are supposed to be orthogonal: |
| - if (nextChildDoc == prevParentDoc) { |
| - throw new IllegalStateException("child query must only match non-parent docs, but parent docID=" + nextChildDoc + " matched childScorer=" + childScorer.getClass()); |
| - } |
| - |
| final int nd = nextDoc(); |
| //System.out.println(" return nextParentDoc=" + nd); |
| return nd; |
| diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java |
| index 1e6c477..e841369 100644 |
| --- a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java |
| +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java |
| @@ -1389,7 +1389,6 @@ public class TestBlockJoin extends LuceneTestCase { |
| d.close(); |
| } |
| |
| - // LUCENE-4968 |
| public void testChildQueryMatchesParent() throws Exception { |
| Directory d = newDirectory(); |
| RandomIndexWriter w = new RandomIndexWriter(random(), d); |
| @@ -1423,7 +1422,7 @@ public class TestBlockJoin extends LuceneTestCase { |
| IndexReader r = w.getReader(); |
| w.close(); |
| |
| - // illegally matches parent: |
| + // childQuery matches parent: |
| Query childQuery = new TermQuery(new Term("parentText", "text")); |
| Filter parentsFilter = new FixedBitSetCachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("isParent", "yes")))); |
| ToParentBlockJoinQuery childJoinQuery = new ToParentBlockJoinQuery(childQuery, parentsFilter, ScoreMode.Avg); |
| @@ -1434,13 +1433,19 @@ public class TestBlockJoin extends LuceneTestCase { |
| ToParentBlockJoinCollector c = new ToParentBlockJoinCollector(new Sort(new SortField("parentID", SortField.Type.STRING)), |
| 10, true, true); |
| |
| - try { |
| - newSearcher(r).search(parentQuery, c); |
| - fail("should have hit exception"); |
| - } catch (IllegalStateException ise) { |
| - // expected |
| - } |
| + newSearcher(r).search(parentQuery, c); |
| + TopGroups<Integer> groups = c.getTopGroups(childJoinQuery, null, 0, 10, 0, false); |
| + |
| + // Two parents: |
| + assertEquals(2, groups.totalGroupCount.intValue()); |
| |
| + GroupDocs<Integer> group = groups.groups[0]; |
| + Document doc = r.document(group.groupValue.intValue()); |
| + assertEquals("0", doc.get("parentID")); |
| + |
| + group = groups.groups[1]; |
| + doc = r.document(group.groupValue.intValue()); |
| + assertEquals("1", doc.get("parentID")); |
| r.close(); |
| d.close(); |
| } |
| diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinValidation.java b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinValidation.java |
| index a2b6360..bb574cd 100644 |
| --- a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinValidation.java |
| +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinValidation.java |
| @@ -76,34 +76,6 @@ public class TestBlockJoinValidation extends LuceneTestCase { |
| } |
| |
| @Test |
| - public void testNextDocValidationForToParentBjq() throws Exception { |
| - Query parentQueryWithRandomChild = createChildrenQueryWithOneParent(getRandomChildNumber(0)); |
| - ToParentBlockJoinQuery blockJoinQuery = new ToParentBlockJoinQuery(parentQueryWithRandomChild, parentsFilter, ScoreMode.None); |
| - thrown.expect(IllegalStateException.class); |
| - thrown.expectMessage("child query must only match non-parent docs"); |
| - indexSearcher.search(blockJoinQuery, 1); |
| - } |
| - |
| - @Test |
| - public void testAdvanceValidationForToParentBjq() throws Exception { |
| - int randomChildNumber = getRandomChildNumber(0); |
| - // we need to make advance method meet wrong document, so random child number |
| - // in BJQ must be greater than child number in Boolean clause |
| - int nextRandomChildNumber = getRandomChildNumber(randomChildNumber); |
| - Query parentQueryWithRandomChild = createChildrenQueryWithOneParent(nextRandomChildNumber); |
| - ToParentBlockJoinQuery blockJoinQuery = new ToParentBlockJoinQuery(parentQueryWithRandomChild, parentsFilter, ScoreMode.None); |
| - // advance() method is used by ConjunctionScorer, so we need to create Boolean conjunction query |
| - BooleanQuery conjunctionQuery = new BooleanQuery(); |
| - WildcardQuery childQuery = new WildcardQuery(new Term("child", createFieldValue(randomChildNumber))); |
| - conjunctionQuery.add(new BooleanClause(childQuery, BooleanClause.Occur.MUST)); |
| - conjunctionQuery.add(new BooleanClause(blockJoinQuery, BooleanClause.Occur.MUST)); |
| - |
| - thrown.expect(IllegalStateException.class); |
| - thrown.expectMessage("child query must only match non-parent docs"); |
| - indexSearcher.search(conjunctionQuery, 1); |
| - } |
| - |
| - @Test |
| public void testNextDocValidationForToChildBjq() throws Exception { |
| Query parentQueryWithRandomChild = createParentsQueryWithOneChild(getRandomChildNumber(0)); |
| |