@Override public void extractTerms(final Set<Term> terms) { for (final NodeBooleanClause clause : clauses) { clause.getQuery().extractTerms(terms); } }
@Override protected void initWeights(final IndexSearcher searcher) throws IOException { weights = new ArrayList<Weight>(clauses.size()); for (int i = 0; i < clauses.size(); i++) { final NodeBooleanClause c = clauses.get(i); final NodeQuery q = c.getQuery(); weights.add(q.createWeight(searcher)); } }
/** * Adds a clause to a boolean query. * * @throws TooManyClauses * if the new number of clauses exceeds the maximum clause number * @see #getMaxClauseCount() */ public void add(final NodeBooleanClause clause) { if (clauses.size() >= maxClauseCount) { throw new TooManyClauses(); } clauses.add(clause); // keep clause synchronised in term of constraint management clause.getQuery().setLevelConstraint(levelConstraint); clause.getQuery().setNodeConstraint(lowerBound, upperBound); clause.getQuery().setAncestorPointer(ancestor); }
/** * Adds a clause to a tuple query. * * @throws TooManyClauses * if the new number of clauses exceeds the maximum clause number * @see #getMaxClauseCount() */ public void add(final NodeBooleanClause clause) { super.addChild(clause.getQuery(), clause.getOccur()); }
@Override protected void setAncestorPointer(final NodeQuery ancestor) { super.setAncestorPointer(ancestor); // keep clauses synchronised for (final NodeBooleanClause clause : clauses) { clause.getQuery().setAncestorPointer(ancestor); } }
@Override public void setLevelConstraint(final int levelConstraint) { super.setLevelConstraint(levelConstraint); // keep clauses synchronised for (final NodeBooleanClause clause : clauses) { clause.getQuery().setLevelConstraint(levelConstraint); } }
@Override protected void initWeights(final IndexSearcher searcher) throws IOException { weights = new ArrayList<Weight>(clauses.size()); for (int i = 0; i < clauses.size(); i++) { final NodeBooleanClause c = clauses.get(i); final NodeQuery q = c.getQuery(); // pass to child query the node contraints q.setNodeConstraint(lowerBound, upperBound); q.setLevelConstraint(levelConstraint); // transfer ancestor pointer to child q.setAncestorPointer(ancestor); weights.add(q.createWeight(searcher)); } }
@Override public void setNodeConstraint(final int lowerBound, final int upperBound) { super.setNodeConstraint(lowerBound, upperBound); // keep clauses synchronised for (final NodeBooleanClause clause : clauses) { clause.getQuery().setNodeConstraint(lowerBound, upperBound); } }
else if (c.isRequired()) buffer.append("+"); final Query subQuery = c.getQuery(); if (subQuery != null) { if (subQuery instanceof NodeBooleanQuery) { // wrap sub-bools in parens
private TwigQuery rewriteClauses(TwigQuery clone, final IndexReader reader) throws IOException { for (int i = 0 ; i < clauses.size(); i++) { final NodeBooleanClause c = clauses.get(i); final NodeQuery query = (NodeQuery) c.getQuery().rewrite(reader); if (query != c.getQuery()) { // clause rewrote: must clone if (clone == null) { clone = (TwigQuery) this.clone(); // clone and set root since clone is null, i.e., root has not been rewritten clone.root = (NodeQuery) this.root.clone(); // copy ancestor clone.root.setAncestorPointer(ancestor); } // set root as ancestor query.setAncestorPointer(clone.root); clone.clauses.set(i, new NodeBooleanClause(query, c.getOccur())); } } return clone; }
else if (c.isRequired()) buffer.append("+"); final Query subQuery = c.getQuery(); if (subQuery != null) { if (subQuery instanceof TwigQuery ||
@Override public void setLevelConstraint(final int levelConstraint) { // store the current level constraint before updating final int oldLevelConstraint = this.levelConstraint; // update level constraint super.setLevelConstraint(levelConstraint); // update level constraint of the root root.setLevelConstraint(levelConstraint); // update level of childs and descendants NodeQuery q; for (final NodeBooleanClause clause : clauses) { q = clause.getQuery(); // compute delta between old level and descendant level final int levelDelta = q.getLevelConstraint() - oldLevelConstraint; // update level of descendant q.setLevelConstraint(levelConstraint + levelDelta); } }
private void checkBooleanTerms(final NodeTermRangeQuery query, final String... terms) throws IOException { query.setRewriteMethod(new MultiNodeTermQuery.TopTermsScoringNodeBooleanQueryRewrite(50)); final NodeBooleanQuery bq = (NodeBooleanQuery) searcher.rewrite(query); final Set<String> allowedTerms = new HashSet<String>(Arrays.asList(terms)); assertEquals(allowedTerms.size(), bq.clauses().size()); for (final NodeBooleanClause c : bq.clauses()) { assertTrue(c.getQuery() instanceof NodeTermQuery); final NodeTermQuery tq = (NodeTermQuery) c.getQuery(); final String term = tq.getTerm().text(); assertTrue("invalid term: "+ term, allowedTerms.contains(term)); allowedTerms.remove(term); // remove to fail on double terms } assertEquals(0, allowedTerms.size()); }
fail = true; final Explanation r = new Explanation(0.0f, "no match on required " + "clause (" + c.getQuery().toString() + ")"); sumExpl.addDetail(r); final Explanation r = new Explanation(0.0f, "match on prohibited clause (" + c.getQuery().toString() + ")"); r.addDetail(e); sumExpl.addDetail(r); "clause (" + c.getQuery().toString() + ")"); r.addDetail(e); sumExpl.addDetail(r);
fail = true; final Explanation r = new Explanation(0.0f, "no match on required " + "clause (" + c.getQuery().toString() + ")"); sumExpl.addDetail(r); final Explanation r = new Explanation(0.0f, "match on prohibited clause (" + c.getQuery().toString() + ")"); r.addDetail(e); sumExpl.addDetail(r); "clause (" + c.getQuery().toString() + ")"); r.addDetail(e); sumExpl.addDetail(r);
@Test public void testSetLevelConstraint() { final TwigQuery tq1 = new TwigQuery(2); tq1.addDescendant(2, new NodeTermQuery(new Term("field", "value")), Occur.MUST); assertEquals(2, tq1.getLevelConstraint()); // Descendant node level must be relative to the twig level assertEquals(4, tq1.clauses().get(0).getQuery().getLevelConstraint()); tq1.setLevelConstraint(3); assertEquals(3, tq1.getLevelConstraint()); // level of descendant node must have been updated assertEquals(5, tq1.clauses().get(0).getQuery().getLevelConstraint()); final TwigQuery tq2 = new TwigQuery(); tq2.addChild(tq1, Occur.MUST); // level of tq1 must have been updated assertEquals(2, tq1.getLevelConstraint()); // level of descendant node must have been updated assertEquals(4, tq1.clauses().get(0).getQuery().getLevelConstraint()); final TwigQuery tq3 = new TwigQuery(3); tq3.addRoot(tq2); // level of tq2 must have been updated assertEquals(3, tq2.getLevelConstraint()); // level of tq1 must have been updated assertEquals(4, tq1.getLevelConstraint()); // level of descendant node must have been updated assertEquals(6, tq1.clauses().get(0).getQuery().getLevelConstraint()); }
@Test public void testRewriteTwigQueryRoot() throws IOException { // if the root node of a twig query is another twig query, then they must // be merged final TwigQuery tq2 = new TwigQuery(2); tq2.addRoot(new NodeTermQuery(new Term("root2", "root2"))); tq2.addChild(new NodeTermQuery(new Term("child2", "child2")), Occur.MUST); tq2.setBoost(0.5f); final TwigQuery tq1 = new TwigQuery(); tq1.addRoot(tq2); tq1.addChild(new NodeTermQuery(new Term("child1", "child1")), Occur.MUST); tq1.setBoost(0.5f); final NodeQuery q = (NodeQuery) tq1.rewrite(null); assertTrue(q instanceof TwigQuery); final TwigQuery tq = (TwigQuery) q; // level and boosst must be the same than for tq1 assertEquals(1, tq.getLevelConstraint()); assertEquals(tq.getBoost(), tq1.getBoost(), 0); // root must not be the same than for tq2 (it has been cloned) assertNotSame(tq.getRoot(), tq2.getRoot()); // root must be equal to the root of tq2 assertEquals(tq.getRoot(), tq2.getRoot()); // clauses must be merged assertEquals(2, tq.clauses().size()); for (final NodeBooleanClause clause : tq.clauses()) { assertEquals(2, clause.getQuery().getLevelConstraint()); assertSame(tq.getRoot(), clause.getQuery().ancestor); } }
@Test public void testSetAncestorPointer() { final NodeTermQuery term = new NodeTermQuery(new Term("field", "value")); final TwigQuery tq1 = new TwigQuery(); tq1.addDescendant(2, term, Occur.MUST); // ancestor of term query must be the root of the twig assertSame(tq1.getRoot(), term.ancestor); // ancestor of the twig must be null assertNull(tq1.ancestor); final TwigQuery tq2 = new TwigQuery(); tq2.addChild(tq1, Occur.MUST); // ancestor of tq1 and of its root must have been updated assertSame(tq2.getRoot(), tq1.ancestor); assertSame(tq2.getRoot(), tq1.getRoot().ancestor); // ancestor of tq1's descendant must have not changed assertEquals(4, tq1.clauses().get(0).getQuery().getLevelConstraint()); final TwigQuery tq3 = new TwigQuery(3); tq3.addRoot(tq2); // ancestor of tq2 and of its root must be the ancestor of tq3 assertSame(tq3.ancestor, tq2.ancestor); assertSame(tq2.ancestor, tq2.getRoot().ancestor); }