@Override public void setBoost(final float b) { nodeQuery.setBoost(b); }
@Override public Query rewrite(final IndexReader reader) throws IOException { NodeSpanQuery clone = null; NodeQuery rewritten = (NodeQuery) this.query.rewrite(reader); if (rewritten != this.query) { clone = this.clone(); // transfer constraints rewritten.setNodeConstraint(lowerBound, upperBound); rewritten.setLevelConstraint(levelConstraint); // transfer ancestor pointer rewritten.setAncestorPointer(ancestor); clone.query = rewritten; } if (clone != null) { return clone; // some clauses rewrote } else { return this; // no clauses rewrote } }
@Override public void extractTerms(final Set<Term> terms) { // TODO: OK to not add any terms when wrapped a filter // and used with MultiSearcher, but may not be OK for // highlighting. // If a query was wrapped, we delegate to query. if (query != null) query.extractTerms(terms); }
/** * Adds a root query. * <p> * Overwrite the level and node constraints of the root query with the * currently defined level and node constraints of the twig query. */ public void addRoot(final NodeQuery root) { this.root = root; // set the node constraint= root.setNodeConstraint(lowerBound, upperBound); // set level constraint root.setLevelConstraint(levelConstraint); // set the ancestor root.setAncestorPointer(ancestor); }
@Override public void setLevelConstraint(final int levelConstraint) { // Do not update the level constraint if it is the sentinel value - cf. #19 if (levelConstraint != -1) { // 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); } } }
NodeQuery query = (NodeQuery) c.getQuery().rewrite(reader); query = (NodeQuery) query.clone(); // then clone before boost query.setBoost(this.getBoost() * query.getBoost()); query.setNodeConstraint(lowerBound, upperBound); query.setLevelConstraint(levelConstraint); query.setAncestorPointer(ancestor); final NodeQuery query = (NodeQuery) c.getQuery().rewrite(reader); if (query != c.getQuery()) { // clause rewrote: must clone if (clone == null) { query.setNodeConstraint(lowerBound, upperBound); query.setLevelConstraint(levelConstraint); query.setAncestorPointer(ancestor);
@Override public Query toQuery(final boolean proxy) throws QueryNodeException { final com.sindicetech.siren.search.node.NodeQuery query = (com.sindicetech.siren.search.node.NodeQuery) parser.parse(booleanExpression, ""); if (this.hasLevel()) { query.setLevelConstraint(this.getLevel()); } if (this.hasRange()) { query.setNodeConstraint(this.getLowerBound(), this.getUpperBound()); } if (this.hasBoost()) { query.setBoost(this.getBoost()); } // should we wrap the query into a lucene proxy if (proxy) { return new LuceneProxyNodeQuery(query); } return query; }
@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 constraints q.setNodeConstraint(lowerBound, upperBound); q.setLevelConstraint(levelConstraint); // transfer ancestor pointer to child q.setAncestorPointer(ancestor); weights.add(q.createWeight(searcher)); } }
@Override protected NodeBooleanQuery getTopLevelQuery(final NodeQuery query) { NodeBooleanQuery q = new NodeBooleanQuery(); // set level and node constraints q.setLevelConstraint(query.getLevelConstraint()); q.setNodeConstraint(query.getNodeConstraint()[0], query.getNodeConstraint()[1]); // set ancestor q.setAncestorPointer(query.ancestor); return q; }
@Override public NodeQuery build(final QueryNode queryNode) throws QueryNodeException { final NodeQueryNode node = (NodeQueryNode) queryNode; final String field = node.getField().toString(); final String expr = node.getValue().toString(); final NodeQuery query = (NodeQuery) keywordParser.parse(expr, field); // check if the node has a level constraint if (node.getTag(LevelPropertyParser.LEVEL_PROPERTY) != null) { query.setLevelConstraint((Integer) node.getTag(LevelPropertyParser.LEVEL_PROPERTY)); } // check if the node has a node range constraint if (node.getTag(RangePropertyParser.RANGE_PROPERTY) != null) { final int[] range = (int[]) node.getTag(RangePropertyParser.RANGE_PROPERTY); query.setNodeConstraint(range[0], range[1]); } return query; }
@Override protected OrSpanQuery getTopLevelQuery(final NodeQuery query) { OrSpanQuery q = new OrSpanQuery(); // set level and node constraints q.setLevelConstraint(query.getLevelConstraint()); q.setNodeConstraint(query.getNodeConstraint()[0], query.getNodeConstraint()[1]); // set ancestor q.setAncestorPointer(query.getAncestorPointer()); return q; }
@Override public void setNodeConstraint(final int lowerBound, final int upperBound) { super.setNodeConstraint(lowerBound, upperBound); // keep root query synchronised with twig query root.setNodeConstraint(lowerBound, upperBound); }
@Override public void setLevelConstraint(final int levelConstraint) { super.setLevelConstraint(levelConstraint); // keep clauses synchronised for (final NodeBooleanClause clause : clauses) { clause.getQuery().setLevelConstraint(levelConstraint); } }
@Test public void testRewriteEmptyClauses() throws IOException { final TwigQuery tq = new TwigQuery(2); tq.addRoot(new NodeTermQuery(new Term("field", "value"))); tq.setBoost(0.5f); // it must be rewritten into the root query final NodeQuery q = (NodeQuery) tq.rewrite(null); assertTrue(q instanceof NodeTermQuery); assertEquals(2, q.getLevelConstraint()); assertEquals(tq.getBoost(), q.getBoost(), 0); assertSame(tq.ancestor, q.ancestor); }
/** * Adds a child clause to the twig query. * * @throws TooManyClauses * if the new number of clauses exceeds the maximum clause number * @see #getMaxClauseCount() */ public void addChild(final NodeQuery query, final NodeBooleanClause.Occur occur) { // set the level constraint on the query query.setLevelConstraint(levelConstraint + 1); // set the ancestor pointer query.setAncestorPointer(root); // add the query to the clauses this.addClause(new NodeBooleanClause(query, occur)); }
@Override public NodeQuery rewrite(final IndexReader reader) throws IOException { if (query != null) { NodeQuery rewritten = (NodeQuery) query.rewrite(reader); if (rewritten != query) { rewritten = new NodeConstantScoreQuery(rewritten); rewritten.setBoost(this.getBoost()); return rewritten; } } return this; }
@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()); }
@Override public Query rewrite(final IndexReader reader) throws IOException { final Query rewroteQuery = nodeQuery.rewrite(reader); if (nodeQuery == rewroteQuery) { return this; } final LuceneProxyNodeQuery q = new LuceneProxyNodeQuery((NodeQuery) rewroteQuery); q.setBoost(nodeQuery.getBoost()); return q; }
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; }
@Test public void testSetAncestorPointer() { NodeSpanQuery term1 = new NodeSpanQuery(ntq("aaa").getQuery()); final TwigQuery twig = new TwigQuery(); term1.setAncestorPointer(twig); assertSame(twig, term1.getAncestorPointer()); // inner query must have been updated assertSame(twig, term1.getQuery().getAncestorPointer()); }