/**
* Copyright 2014 National University of Ireland, Galway.
*
* This file is part of the SIREn project. Project and contact information:
*
* https://github.com/rdelbru/SIREn
*
* Licensed 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.
*/
package org.sindice.siren.search.node;
import static org.sindice.siren.analysis.MockSirenDocument.doc;
import static org.sindice.siren.analysis.MockSirenToken.node;
import static org.sindice.siren.analysis.MockSirenToken.token;
import static org.sindice.siren.search.AbstractTestSirenScorer.BooleanClauseBuilder.must;
import static org.sindice.siren.search.AbstractTestSirenScorer.BooleanClauseBuilder.not;
import static org.sindice.siren.search.AbstractTestSirenScorer.BooleanClauseBuilder.should;
import static org.sindice.siren.search.AbstractTestSirenScorer.NodeBooleanQueryBuilder.nbq;
import static org.sindice.siren.search.AbstractTestSirenScorer.TwigChildBuilder.child;
import static org.sindice.siren.search.AbstractTestSirenScorer.TwigDescendantBuilder.desc;
import static org.sindice.siren.search.AbstractTestSirenScorer.TwigQueryBuilder.twq;
import java.io.IOException;
import java.util.Collection;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer.ChildScorer;
import org.junit.Test;
import org.sindice.siren.index.DocsAndNodesIterator;
import org.sindice.siren.index.codecs.RandomSirenCodec.PostingsFormatType;
import org.sindice.siren.search.AbstractTestSirenScorer;
public class TestTwigScorer extends AbstractTestSirenScorer {
@Override
protected void configure() throws IOException {
this.setAnalyzer(AnalyzerType.MOCK);
this.setPostingsFormat(PostingsFormatType.RANDOM);
}
@Test(expected=UnsupportedOperationException.class)
public void testEmptyRootScorer()
throws Exception {
this.addDocuments(
doc(token("aaa", node(1)), token("req", node(1)),
token("bbb", node(1,0)), token("ccc", node(1,0)))
);
NodeScorer scorer = this.getScorer(
twq(1)
);
scorer.nextCandidateDocument();
}
@Test
public void testNonMatchingRootQuery()
throws Exception {
this.addDocuments(
doc(token("aaa", node(1)), token("req", node(1)),
token("bbb", node(1,0)), token("ccc", node(1,0))),
doc(token("ccc", node(1)), token("req", node(1)), token("bbb", node(1,0)))
);
// the term does not occur
NodeScorer scorer = this.getScorer(
twq(1, should("eee")).with(child(must("bbb")))
);
assertTrue(scorer == null);
// the boolean condition is not met
scorer = this.getScorer(
twq(1, must(nbq(must("req"), not("aaa"), not("ccc")))).with(child(must("bbb")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
// test for the EmptyRootScorer
scorer = this.getScorer(
twq(1).with(child(must("ccc"))).with(child(should("bbb")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testSingleChild() throws Exception {
this.addDocuments(
doc(token("aaa", node(1)), token("bbb", node(1,0)), token("aaa", node(2))),
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1,0))),
doc(token("aaa", node(5,3,6,3)), token("bbb", node(5,3,6,3,7)))
);
NodeScorer scorer = this.getScorer(
twq(1, must("aaa")).with(child(must("bbb")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa")).with(child(must("bbb")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(4, must("aaa")).with(child(must("bbb")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(5,3,6,3), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testEmptyRoot() throws Exception {
this.addDocuments(
doc(token("aaa", node(1)), token("bbb", node(1,0)), token("aaa", node(2))),
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1,0))),
doc(token("aaa", node(5,3,6,3)), token("bbb", node(5,3,6,3,7)))
);
NodeScorer scorer = this.getScorer(
twq(1).with(child(must("bbb")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2).with(child(must("bbb")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testSingleDescendant() throws Exception {
this.addDocuments(
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1))),
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1,0))),
doc(token("aaa", node(1,0)), token("bbb", node(1,1,2,3)))
);
final NodeScorer scorer = this.getScorer(
twq(2, must("aaa")).with(desc(2, must("bbb")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testChildDescendant() throws Exception {
this.addDocuments(
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1,0)), token("ccc", node(1,0,1,0))),
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1,0)), token("ccc", node(1,0,4)))
);
final NodeScorer scorer = this.getScorer(
twq(2, must("aaa")).with(desc(2, must("bbb")))
.with(child(must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testBooleanChild() throws Exception {
this.addDocuments(
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1)), token("ccc", node(1,0,4))),
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1)), token("ccc", node(1,0,1)))
);
NodeScorer scorer = this.getScorer(
twq(2, must("aaa")).with(child(must("bbb"), must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
final float d1score10 = scorer.scoreInNode();
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa")).with(child(must("bbb"), should("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
final float d0score10 = scorer.scoreInNode();
assertTrue(d1score10 + " > " + d0score10, d1score10 > d0score10);
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa")).with(child(must("bbb"), not("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testBooleanRoot() throws Exception {
this.addDocuments(
doc(token("aaa", node(1,0)), token("bbb", node(1,1)), token("ccc", node(1,0,1))),
doc(token("aaa", node(1,0)), token("bbb", node(1,0)), token("ccc", node(1,0,1)))
);
NodeScorer scorer = this.getScorer(
twq(2, must("aaa"), must("bbb")).with(child(must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
final float d1score10 = scorer.scoreInNode();
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa"), should("bbb")).with(child(must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
final float d0score10 = scorer.scoreInNode();
assertTrue(d1score10 + " > " + d0score10, d1score10 > d0score10);
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa"), not("bbb")).with(child(must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testBooleanClause() throws Exception {
this.addDocuments(
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1)), token("ccc", node(1,0,4))),
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1))),
doc(token("aaa", node(1,0)))
);
NodeScorer scorer = this.getScorer(
twq(2, must("aaa")).with(child(must("bbb")))
.optional(child(must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa")).with(child(must("bbb")))
.without(child(must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa")).optional(child(must("bbb")))
.without(child(must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
// Test with only a prohibited clause
scorer = this.getScorer(
twq(2, must("aaa")).without(child(must("ccc")))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testNestedTwig() throws Exception {
this.addDocuments(
doc(token("aaa", node(1,0)), token("bbb", node(1,0,1)), token("ccc", node(1,0,1,0)),
token("eee", node(1,0,4)), token("fff", node(1,0,4,1)),
token("ggg", node(1,0,4,1)), token("hhh", node(1,0,1)))
);
NodeScorer scorer = this.getScorer(
twq(2, must("aaa")).with(child(must(
twq(3, must("bbb")).with(child(must("ccc")))
)))
.with(child(must(
twq(3, must("eee")).with(child(must("fff")))
)))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
final float s0 = scorer.scoreInNode();
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa")).with(child(must(
twq(3, must("bbb"), must("hhh")).with(child(must("ccc")))
)))
.with(child(must(
twq(3, must("eee")).with(child(must("fff")))
)))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
final float s1 = scorer.scoreInNode();
assertTrue(s1 + " > " + s0, s1 > s0);
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa")).with(child(must(
twq(3, must("bbb")).with(child(must("ccc")))
)))
.with(child(must(
twq(3, must("eee")).with(child(must("fff"), must("ggg")))
)))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
final float s2 = scorer.scoreInNode();
assertTrue(s2 + " > " + s0, s2 > s0);
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
scorer = this.getScorer(
twq(2, must("aaa")).with(child(must(
twq(3, must("bbb"), must("hhh")).with(child(must("ccc")))
)))
.with(child(must(
twq(3, must("eee")).with(child(must("fff"), must("ggg")))
)))
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(1,0), scorer.node());
final float s3 = scorer.scoreInNode();
assertTrue(s3 + " > " + s0, s3 > s1);
assertTrue(s3 + " > " + s2, s3 > s2);
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testNodeConstraints() throws Exception {
this.addDocuments(
doc(token("aaa", node(2)), token("bbb", node(2,0))),
doc(token("aaa", node(0)), token("bbb", node(1,0))),
doc(token("aaa", node(4)), token("bbb", node(4,0)))
);
final NodeScorer scorer = this.getScorer(
twq(1, must("aaa")).with(child(must("bbb")))
.bound(1,3)
);
assertTrue(scorer.nextCandidateDocument());
assertEquals(0, scorer.doc());
assertEquals(node(-1), scorer.node());
assertTrue(scorer.nextNode());
assertEquals(node(2), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(1, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertTrue(scorer.nextCandidateDocument());
assertEquals(2, scorer.doc());
assertEquals(node(-1), scorer.node());
assertFalse(scorer.nextNode());
assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node());
assertEndOfStream(scorer);
}
@Test
public void testRewriteRootAndClause() throws Exception {
this.addDocuments(
doc(token("aaa", node(2)), token("bbb", node(2,0)))
);
final NodeScorer scorer = this.getScorer(
twq(1, must("aaa")).with(child(must("bbb")))
);
assertTrue(scorer instanceof TwigScorer);
final TwigScorer ts = (TwigScorer) scorer;
final Collection<ChildScorer> childs = ts.getChildren();
assertEquals(2, childs.size());
// The root and child must have been rewritten into NodeTermScorer
NodeScorer s = null;
for (final ChildScorer child : childs) {
s = (NodeScorer) child.child;
if (s instanceof AncestorFilterScorer) {
s = ((AncestorFilterScorer) child.child).getScorer();
}
assertTrue(s instanceof NodeTermScorer);
}
}
@Test
public void testRewriteWithZeroClause() throws Exception {
this.addDocuments(
doc(token("aaa", node(2)), token("bbb", node(2,0)))
);
final NodeScorer scorer = this.getScorer(
twq(1, must("aaa"))
);
// Should be rewritten into a NodeTermScorer
assertTrue(scorer instanceof NodeTermScorer);
}
@Test
public void testNoRequiredAndOptionalClause() throws IOException {
// if the root node of a twig query is empty, and if there is no required
// and optional clauses, it should return no result
// optional clauses with terms that do not exist
Query query = twq(1)
.optional(child(must("ddd")))
.optional(child(must("eee")))
.getLuceneProxyQuery();
assertEquals(0, searcher.search(query, 100).totalHits);
}
@Test
public void testNullAncestorQuery() throws IOException {
// when a twig with an empty root and only one clause is rewritten in an
// ancestor query, if the ancestor query is composed of terms that do not
// exist it should return no result
// optional clauses with terms that do not exist
final Query query = twq(1)
.optional(child(must("eee")))
.getLuceneProxyQuery();
assertEquals(0, searcher.search(query, 100).totalHits);
}
}